MS: this is a version of Recursive curves that avoids floating point operations:
Note that this is pure sport - the extra optimisation is not really relevant here, there isnot much further improvement from the original version as the app is I/O bound (drawing on the canvas).
Also note that this implementation makes additional assumptions:
proc main {} { pack [canvas .c -width 240 -height 280] set ::points {150 190} # 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 . <Return> {exec wish $argv0 &; exit} }
# This just sets up the parameters for # table-based ops; we assume here that # the initial angle is 0.
proc setParams {len angle minlen} { global parList set maxDepth [expr {(1+floor(2*log($len/$minlen)/log(2)))}] set minlen [expr {$len/pow(sqrt(2),$maxDepth)}] set minlen0 [expr {$minlen/sqrt(2)}] set parList {} lappend parList [list 0.0 $minlen ];# 0 lappend parList [list $minlen0 $minlen0];# 1 lappend parList [list $minlen 0.0 ];# 2 lappend parList [list $minlen0 -$minlen0];# 3 lappend parList [list 0.0 -$minlen ];# 4 lappend parList [list -$minlen0 -$minlen0];# 5 lappend parList [list -$minlen 0.0 ];# 6 lappend parList [list -$minlen0 $minlen0];# 7 return [expr {int($maxDepth)}] }
# C curve drawer: assumes initial angle 0
proc ccurve {w len angle minlen} { set maxDepth [setParams $len $angle $minlen] ccurveInt $w $maxDepth $angle }
proc ccurveInt {w depth angle} {
while {$depth} { incr depth -1 ccurveInt $w $depth [expr {$angle + 1}] incr angle -1 } plotline $w $angle }
# Dragon curve drawer: assumes initial angle 0, initial s 1
proc dragon {w len angle s minlen} { set maxDepth [setParams $len $angle $minlen] dragonInt $w $maxDepth $angle $s } proc dragonInt {w depth angle s} { while {$depth} { incr depth -1 dragonInt $w $depth [expr {$angle + $s}] 1 if {$s == 1} { incr angle -1 set s -1 } else { incr angle 1 } } plotline $w $angle }
# Plot a line from last end point in specified direction and length
proc plotline {w ang} { global points set idx [expr {$ang%8}] if {$idx < 0} { incr $idx 8 } foreach {xadd yadd} [lindex $::parList $idx] { set x [expr {[lindex $points end-1]-$xadd}] set y [expr {[lindex $points end ]-$yadd}] } if {[llength [lappend points $x $y]]>200} { $w create line $points set points [list $x $y] update } }
# Let's go!
main