GWM Another (more familiar) illusion, this allows the user to try out a range of arrow angles and adjust the length of one line until the lines appear equal length. After 10 repeats, using slightly different length lines, an average ratio of length chosen to true length is printed to the console. Reverse the direction of the arrow ends, and repeat. With sharp arrows (20 degrees) the effect reaches about 5 to 10% reasonably repeatably for me.
See also
Atlantis Cafe Illusion &
Bulging Line Illusion # Optical illusions
# i) are these the same length?- adjust the arrow angle and the length to identify maximum illusion
proc drawarrowline { frm len y angle mid} {
set r 30
set dx [expr $r*cos($angle*.017345)]
set dy [expr $r*sin($angle*.017345)]
$frm create line [expr $mid-$len] $y [expr $len+$mid] $y -fill black -width 3
lappend line [expr $mid-$len - $dx] [expr $y + $dy] [expr $mid-$len] $y [expr $mid-$len - $dx] [expr $y - $dy]
$frm create line $line -fill black -width 3
lset line []
lappend line [expr $mid +$len + $dx] [expr $y + $dy] [expr $mid +$len] $y [expr $mid +$len + $dx] [expr $y - $dy]
$frm create line $line -fill black -width 3
}
proc redraw { va} { ;# l2 is length of the second line; angle the angle of the arrows
global len angle reflen
catch [destroy .frm] {} ;# delete drawing area. Same as clear.
set wid 125
set frm [canvas .frm -width [expr $wid*2] -height 140]
# draw 2 lines of length xx with 'arrows' at opposite angles
drawarrowline $frm $reflen 50 $angle $wid
drawarrowline $frm [expr int(35+$len*0.3)] 100 [expr int(180-$angle)] $wid
pack .frm
}
proc checkok {} {
global len angle reflen suml ntries
lappend suml [expr 100*(35+$len*0.3)/($reflen)]
incr ntries
# set a new random test length and jumble up the uer set to remove hints
set reflen [expr 42 + 15*rand()]
set len [expr 90*rand()]
if {$ntries>10} { Scores
} else { redraw 0 ;# draw the new lines
}
}
proc Scores {} {
global len angle reflen suml ntries
if {$ntries>0} {
set sum 0
foreach score $suml {
puts "Score $score"
set sum [expr $sum+$score]
}
puts "After $ntries, average [format %.1f [expr $sum/$ntries]]% of desired length with angle $angle degrees."
set reflen [expr 42 + 15*rand()]
set len [expr 90*rand()]
redraw 0
set ntries 0
set suml {}
}
}
proc createArrowIllusion {} {
global len angle reflen ;# arrow length, angle and compare with length
global suml ntries
set ntries 0
set suml {}
set reflen [expr 42 + 15*rand()]
set len 60
set angle 20
catch [destroy .btns] {} ;# delete controls
set btn [frame .btns]
pack $btn -side top
label $btn.inst -text "Adjust Length until the two lines are equal length.\nThen press 'OK' and repeat."
menubutton $btn.angl -menu $btn.angl.opts -text "Set Angle"
set mn [menu $btn.angl.opts ]
for {set i 20} {$i<165} {incr i 20} {
$mn add command -label "$i" -command "set angle $i;redraw 0"
}
scale $btn.len -variable len -orient horizontal -showvalue false -label "Length" -command "redraw"
button $btn.ok -text "OK" -command "checkok"
button $btn.scr -text "Score" -command "Scores"
set btnfrm [frame $btn.frm]
pack $btn.inst $btn.angl $btn.len $btnfrm -side top
pack $btn.ok $btn.scr -side left
wm title . "Arrow Illusion"
}
createArrowIllusion