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 +}