ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> tcl-mac
tcl-mac
[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

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved