[MACTCL] Bad Beziers in canvas widgets
by Revar Desmera other posts by this author
Mar 19 2007 7:04PM messages near this date
Re: [MACTCL] Pinstripe background patches
|
Re: [MACTCL] Bad Beziers in canvas widgets
I've been writing a simple 2D CAD program in TCL/Tk, and I've found
something odd in how the canvas widget draws bezier curves.
That is, it's NOT drawing bezier curves. It's drawing something else.
I've double-checked my math twice, and written routines to generate
line-paths via both straight up calculation and by Bezier
subdivision. They agree with each other, and with the resources on
Bezier curves I've found on the web. When I tell tk to draw the
bezier from the original control points, though, and draw a line of
similar spline steps using my calculated bezier, the two curves are
not even close, except at starting and ending points. I'm talking
dozens of pixels off here.
I've included some example code showing the error.
- Revar
proc bezier_line {coords steps} {
# Generates a number of points along a bezier curve,
# using the cubic bezier formula.
foreach {x0 y0 x1 y1 x2 y2 x3 y3} $coords break
set xc [expr {3.0*($x1-$x0)}]
set xb [expr {3.0*($x2-$x1)-$xc}]
set xa [expr {$x3-$x0-$xc-$xb}]
set yc [expr {3.0*($y1-$y0)}]
set yb [expr {3.0*($y2-$y1)-$yc}]
set ya [expr {$y3-$y0-$yc-$yb}]
set coords {}
set inc [expr {1.0/$steps}]
for {set t 0.0} {$t < 1.0} {set t [expr {$t+$inc}]} {
set mx [expr {$xa*$t*$t*$t + $xb*$t*$t + $xc*$t +$x0}]
set my [expr {$ya*$t*$t*$t + $yb*$t*$t + $yc*$t +$y0}]
lappend coords $mx $my
}
lappend coords $x3 $y3
return $coords
}
proc bezier_split {coords} {
# Mathematically subdivides each bezier curve segment into two
curve
# segments that each exactly match half of the original curve.
set outcoords {}
foreach {x0 y0} [lrange $coords 0 1] break
lappend outcoords $x0 $y0
foreach {x1 y1 x2 y2 x3 y3} [lrange $coords 2 end] {
set mx01 [expr {($x0+$x1)/2.0}]
set my01 [expr {($y0+$y1)/2.0}]
set mx12 [expr {($x1+$x2)/2.0}]
set my12 [expr {($y1+$y2)/2.0}]
set mx23 [expr {($x2+$x3)/2.0}]
set my23 [expr {($y2+$y3)/2.0}]
set mx012 [expr {($mx01+$mx12)/2.0}]
set my012 [expr {($my01+$my12)/2.0}]
set mx123 [expr {($mx12+$mx23)/2.0}]
set my123 [expr {($my12+$my23)/2.0}]
set mx0123 [expr {($mx012+$mx123)/2.0}]
set my0123 [expr {($my012+$my123)/2.0}]
lappend outcoords $mx01 $my01 $mx012 $my012 $mx0123 $my0123
$mx123 $my123 $mx23 $my23 $x3 $y3
set x0 $x3
set y0 $y3
}
return $outcoords
}
canvas .c -width 400 -height 500
pack .c
set path [list 100 50 500 450 -100 450 300 50]
set calcpath [bezier_line $path 48]
set calcpath2 [bezier_split $path]
set calcpath2 [bezier_split $calcpath2]
set calcpath2 [bezier_split $calcpath2]
set calcpath2 [bezier_split $calcpath2]
.c create line $path -fill yellow -smooth 1 -splinesteps 16 -width 5
.c create line $calcpath -fill grey50 -smooth 0 -width 3
.c create line $calcpath2 -fill red -smooth 0 -width 1
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Tcl-mac mailing list
tcl-mac@[...].net
https://lists.sourceforge.net/lists/listinfo/tcl-mac
Thread:
Revar Desmera
Daniel A. Steffen
Revar Desmera
Daniel A. Steffen
Mats Bengtsson
Revar Desmera
Robert Karen
Daniel A. Steffen
Robert Karen
Jeff Hobbs
Oscar Bonilla
Brian Griffin
|