Drawing geometric figures - the result of airplane travel.
The example script shows the use of canvas and geometric figues (regular, convex polygons) with different number of edges based on trigonometric functions.
-gustaf neumann (Aug 2, 2013)
package require Tk package require nx
Class Canvas is a simple convenience wrapper for the tk canvas, which packs itself.
nx::Class create Canvas { :property {canvas .canvas} :property {bg beige} :property {height 500} :property {width 500} :method init {} { canvas ${:canvas} -bg ${:bg} -height ${:height} -width ${:width} pack ${:canvas} } }
Class Area provides a center point (x, y) and a radius
nx::Class create Area { :property {canvas .canvas} :property {x 250} :property {y 250} :property {radius 200} :variable pi [expr {acos(-1)}] :method degree {d} { # # return a coordinate pair on a circle around the center point with # :radius at the provided degrees (0..360) # set x [expr {$d*${:pi}/180.0 - ${:pi}/2.0}] set x0 [expr {cos($x)*${:radius}+${:x}}] set y0 [expr {sin($x)*${:radius}+${:y}}] list $x0 $y0 } :method n-tangle {n} { # # Draw a regular n-tangle (e.g. when n==3, a triangle) inscribed to # a circle with radius :radius # for {set i 0} {$i < $n} {incr i} { set p($i) [:degree [expr {$i*360/$n}]] } lassign $p(0) x0 y0 for {set i 1} {$i < $n} {incr i} { lassign $p($i) x1 y1 ${:canvas} create line $x0 $y0 $x1 $y1 lassign $p($i) x0 y0 } lassign $p(0) x1 y1 ${:canvas} create line $x0 $y0 $x1 $y1 } }
Class Inscribe draws multiple n-tangles with the came center point.
nx::Class create Inscribe -superclass Area { :property {count 4} :property {edges 3} :method init {} { for {set i 0} {$i < ${:count}} {incr i} { ${:canvas} create oval \ [expr {${:x}-${:radius}}] [expr {${:y}-${:radius}}] \ [expr {${:x}+${:radius}}] [expr {${:y}+${:radius}}] :n-tangle ${:edges} set :radius [expr {${:radius}/2.0}] } } }
Class Hull creates an n-tangle with :density hull lines between neighboring edges
nx::Class create Hull -superclass Area { :property {edges 3} :property {density 10} :method n-tangle {n} { for {set i 0} {$i < $n} {incr i} { set p($i) [:degree [expr {$i*360/$n}]] } lassign $p(0) x0 y0 for {set i 1} {$i < $n} {incr i} { lassign $p($i) x1 y1 set line($i) [list $x0 $y0 $x1 $y1] ${:canvas} create line $x0 $y0 $x1 $y1 lassign $p($i) x0 y0 } lassign $p(0) x1 y1 ${:canvas} create line $x0 $y0 $x1 $y1 set line(0) [list $x0 $y0 $x1 $y1] set line($n) [list $x0 $y0 $x1 $y1] for {set i 0} {$i < $n} {incr i} { lassign $line($i) x0 y0 x1 y1 lassign $line([expr {$i+1}]) x2 y2 x3 y3 set dx1 [expr {($x0 - $x1)*1.0/${:density}}] set dy1 [expr {($y0 - $y1)*1.0/${:density}}] set dx2 [expr {($x2 - $x3)*1.0/${:density}}] set dy2 [expr {($y2 - $y3)*1.0/${:density}}] for {set j 1} {$j < ${:density}} {incr j} { ${:canvas} create line [expr {$x0-$dx1*$j}] [expr {$y0-$dy1*$j}] \ [expr {$x2-$dx2*$j}] [expr {$y2-$dy2*$j}] } } } :method init {} { :n-tangle ${:edges} } }
Draw either one larger figure with inner figures or a series of smaller figures next to each other.
set multiple 0 if {$multiple} { # Draw a series of figures next to each other set c [::Canvas new -width 650 -height 750 -bg white] ::Inscribe new -canvas [$c cget -canvas] -x 100 -y 100 -radius 80 -count 7 ::Inscribe new -canvas [$c cget -canvas] -x 300 -y 100 -radius 80 -count 7 -edges 4 ::Inscribe new -canvas [$c cget -canvas] -x 500 -y 100 -radius 80 -count 7 -edges 5 ::Hull new -canvas [$c cget -canvas] -x 100 -y 300 -radius 80 -edges 3 -density 10 ::Hull new -canvas [$c cget -canvas] -x 300 -y 300 -radius 80 -edges 4 -density 10 ::Hull new -canvas [$c cget -canvas] -x 500 -y 300 -radius 80 -edges 5 -density 10 ::Hull new -canvas [$c cget -canvas] -x 300 -y 600 -radius 200 -edges 3 -density 40 } else { # Draw a several series of figures with the same center set c [::Canvas new -width 650 -height 650 -bg white] ::Hull new -canvas [$c cget -canvas] -x 300 -y 320 -radius 300 -edges 5 -density 40 ::Hull new -canvas [$c cget -canvas] -x 300 -y 320 -radius 150 -edges 4 -density 20 ::Hull new -canvas [$c cget -canvas] -x 300 -y 320 -radius 75 -edges 3 -density 10 ::Hull new -canvas [$c cget -canvas] -x 300 -y 320 -radius 30 -edges 5 -density 5 }