if 0 {[Richard Suchenwirth] 2004-01-18 - The C curve is a quite beautiful image created by a simple recursive function, originally described by William Gosper. I met it in the Winston/Horn book on [LISP] and of course wanted to have it in Tcl/Tk too, and on my [PocketPC]. Translation wasn't difficult - somehow Tcl is "the LISP of the 21st century". [http://mini.net/files/ccurve.gif] [http://mini.net/files/dragon.gif] As the code is a bit slow on PocketPC (171 sec for the C curve, 615 sec for the dragon curve!), I chose to [update] the [canvas] after every line segment is drawn, for animation. Also, the related but very different dragon curve was added - I think fractals developed from these studies. So here is yet another weekend fun project, which again demonstrates interesting things in few lines of code: [KPV] See also [Dragon Curve]. } proc main {} { pack [canvas .c -width 240 -height 280] set ::x0 150; set ::y0 190 set ::pi_4 [expr atan(1)] # ETFS configurability: uncomment what you want set t [time {ccurve .c 120 0 2}] #set t [time {dragon .c 160 0 1 2.4}] wm title . "[expr {[lindex $t 0]/1000000.}] sec" bind . {exec wish $argv0 &; exit} } # C curve drawer, translated from Lisp proc ccurve {w len angle minlen} { if {$len<$minlen} { plotline $w $len $angle } else { set len [expr {$len/sqrt(2)}] ccurve $w $len [expr {$angle+$::pi_4}] $minlen ccurve $w $len [expr {$angle-$::pi_4}] $minlen } } # Dragon curve drawer proc dragon {w len angle s minlen} { global pi_4 if {$len<$minlen} { plotline $w $len $angle } else { set len [expr {$len/sqrt(2)}] dragon $w $len [expr {$angle+$s*$pi_4}] 1 $minlen dragon $w $len [expr {$angle-$s*$pi_4}] -1 $minlen } } # Plot a line from last end point in specified direction and length proc plotline {w len ang} { global x0 y0 update set x [expr {$x0-$len*sin($ang)}] set y [expr {$y0-$len*cos($ang)}] $w create line $x0 $y0 $x $y set x0 $x; set y0 $y } # Let's go! main ---- [NEM] Very nice. Of course, the [[update]] call in the code slows it down quite a lot. ccurve takes just over 2 seconds with the update on my box (2.4GHz pentium4), while without the update takes just 0.12 seconds. A marginal speed increase can be had by precomputing the sqrt(2). To get a trade-off between speed and updating the GUI, perhaps it would be better to update the screen once a second or so: proc plotline {w len ang} { global x0 y0 time if {[clock seconds] > $time} { update; set time [clock seconds] } set x [expr {$x0-$len*sin($ang)}] set y [expr {$y0-$len*cos($ang)}] $w create line $x0 $y0 $x $y set x0 $x; set y0 $y } set ::time [clock seconds] main I haven't tested this as it takes less than a second to run on my machine at uni. ---- [Arts and crafts of Tcl-Tk programming]