escargo 24 Mar 2003 - There's a little glitch that appears on a seven-sided figure. If start is set to zero, the glitch appears on the far right-hand side....KPV oops, step size should have been a double, not an int.escargo 24 Mar 2003 - Is there any reason that the minimum number of sides should not be 3? I don't find the 1 and 2 case to be very interesting. (You wanted to show a circle and treat 0 the same as an infinite number of sides?)KPV I was following the convention in Regular Polygons where the number of sides equal to zero is a circle. I really want a scale that goes 0, 3, 4, ... but since this is just throw away demo code I let it stand as is.
proc rp2 {x0 y0 x1 y1 args} {
array set V {-sides 0 -start 90 -extent 360} ;# Default values
foreach {a value} $args {
if {! [info exists V($a)]} {error "unknown option $a"}
if {$value == {}} {error "value of \"$a\" missing"}
set V($a) $value
}
if {$V(-extent) == 0} {return {}}
set xm [expr {($x0+$x1)/2.}]
set ym [expr {($y0+$y1)/2.}]
set rx [expr {$xm-$x0}]
set ry [expr {$ym-$y0}]
set n $V(-sides)
if {$n == 0} { ;# 0 sides => circle
set n [expr {round(($rx+$ry)*0.5)}]
if {$n < 2} {set n 4}
}
set dir [expr {$V(-extent) < 0 ? -1 : 1}] ;# Extent can be negative
if {abs($V(-extent)) > 360} {
set V(-extent) [expr {$dir * (abs($V(-extent)) % 360)}]
}
set step [expr {$dir * 360.0 / $n}]
set numsteps [expr {1 + double($V(-extent)) / $step}]
set xy {}
set DEG2RAD [expr {4*atan(1)*2/360}]
for {set i 0} {$i < int($numsteps)} {incr i} {
set rad [expr {($V(-start) - $i * $step) * $DEG2RAD}]
set x [expr {$rx*cos($rad)}]
set y [expr {$ry*sin($rad)}]
lappend xy [expr {$xm + $x}] [expr {$ym - $y}]
}
# Figure out where last segment should end
if {$numsteps != int($numsteps)} {
# Vecter V1 is last drawn vertext (x,y) from above
# Vector V2 is the edge of the polygon
set rad2 [expr {($V(-start) - int($numsteps) * $step) * $DEG2RAD}]
set x2 [expr {$rx*cos($rad2) - $x}]
set y2 [expr {$ry*sin($rad2) - $y}]
# Vector V3 is unit vector in direction we end at
set rad3 [expr {($V(-start) - $V(-extent)) * $DEG2RAD}]
set x3 [expr {cos($rad3)}]
set y3 [expr {sin($rad3)}]
# Find where V3 crosses V1+V2 => find j s.t. V1 + kV2 = jV3
set j [expr {($x*$y2 - $x2*$y) / ($x3*$y2 - $x2*$y3)}]
lappend xy [expr {$xm + $j * $x3}] [expr {$ym - $j * $y3}]
}
return $xy
}
# Now for code to demonstrate and test it
proc DrawIt {args} {
global S
foreach {x0 y0 x1 y1} [.c cget -scrollregion] break
set bbox [list 20 20 [incr x1 -20] [incr y1 -20]]
.c delete poly
set xy [eval rp2 $bbox -sides $S(sides) -start $S(start) -extent 360]
.c create poly $xy -fill {} -outline black -width 2 -dash - -tag poly
set xy [eval rp2 $bbox -sides $S(sides) -start $S(start) -extent $S(extent)]
.c create poly $xy -fill red -outline {} -tag poly
.c create line $xy -fill red -fill black -width 3 -tag poly
}
pack [frame .bottom] -side bottom -fill x
pack [canvas .c -width 500 -height 500 -bd 2 -relief raised] -fill both -expand 1
bind .c <Configure> {%W config -scrollregion [list 0 0 %w %h] ; DrawIt}
scale .sides -variable S(sides) -orient h -from 0 -to 10 -label Sides -relief ridge
scale .start -variable S(start) -orient h -from 0 -to 360 -label Start -relief ridge
scale .extent -variable S(extent) -orient h -from -360 -to 360 -label Extent -relief ridge
pack .sides .start .extent -side left -in .bottom
array set S {extent 135 sides 4 start 0}
trace variable S w DrawItuniquename 2013jul29This code could use an image to show what it produces:
