From: Revar D. <rev...@gm...> - 2007-03-20 02:01:35
|
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 |
From: Daniel A. S. <st...@ma...> - 2007-03-20 02:27:11
|
Revar, On 20/03/2007, at 3:01, Revar Desmera wrote: > 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. reread canvas.n ;-) you need to use '-smooth raw' for the canvas code to use the interpretation of bezier control points that your manual computation expects... if I use the following in your sample, all 3 curves agree: .c create line $path -fill yellow -smooth raw -splinesteps 16 -width 5 Cheers, Daniel -- ** Daniel A. Steffen Dept. of Mathematics ** ** Macquarie University NSW 2109 Australia ** |
From: Revar D. <rev...@gm...> - 2007-03-20 03:32:21
|
Interesting. The canvas man page I have installed on my system doesn't mention 'raw' at all. Nor does the canvas.n in my CVS checkout, though I've not done a cvs update in a couple months. Are you sure it's in there? - Revar On Mar 19, 2007, at 7:26 PM, Daniel A. Steffen wrote: > Revar, > > On 20/03/2007, at 3:01, Revar Desmera wrote: > >> 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. > > reread canvas.n ;-) > you need to use '-smooth raw' for the canvas code to use the > interpretation of bezier control points that your manual > computation expects... > if I use the following in your sample, all 3 curves agree: > .c create line $path -fill yellow -smooth raw -splinesteps 16 - > width 5 > > Cheers, > > Daniel > > -- > ** Daniel A. Steffen Dept. of Mathematics ** > ** Macquarie University NSW 2109 Australia ** > > |
From: Brian G. <bri...@ea...> - 2007-03-20 04:04:38
|
Hi Revar, The documentation is unclear on this subject. Here's a better description taken from the Tcl 8.5 man page: -smooth smoothMethod smoothMethod must have one of the forms accepted by Tcl_GetBoolean or a line smoothing method. Only true and raw are supported in the core (with bezier being an alias for true), but more can be added at runtime. If a boolean false value or empty string is given, no smoothing is applied. A boolean truth value assumes true smoothing. If the smoothing method is true, this indicates that the line should be drawn as a curve, rendered as a set of quadratic splines: one spline is drawn for the first and second line segments, one for the second and third, and so on. Straight-line segments can be generated within a curve by duplicating the end-points of the desired line segment. If the smoothing method is raw, this indicates that the line should also be drawn as a curve but where the list of coordinates is such that the first coordinate pair (and every third coordinate pair thereafter) is a knot point on a cubic Bezier curve, and the other coordinates are control points on the cubic Bezier curve. Straight line segments can be venerated within a curve by making control points equal to their neighbouring knot points. If the last point is a control point and not a knot point, the point is repeated (one or two times) so that it also becomes a knot point. The reason it's confusing is that the original bezier implementation is not a true implementation, but rather, "... it internally computes a Bezier curve representation of each parabolic spline segment. These Bezier curves are then flattened to produce the points filled into the output arrays." The -smooth values of "bezier" or "true" are maintained for backward compatibility. The value of "raw" was added later and implements the true bezier curve. -Brian On Mar 19, 2007, at 8:32 PM, Revar Desmera wrote: > Interesting. The canvas man page I have installed on my system > doesn't mention 'raw' at all. Nor does the canvas.n in my CVS > checkout, though I've not done a cvs update in a couple months. Are > you sure it's in there? > > - Revar > > > > On Mar 19, 2007, at 7:26 PM, Daniel A. Steffen wrote: > >> Revar, >> >> On 20/03/2007, at 3:01, Revar Desmera wrote: >> >>> 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. >> >> reread canvas.n ;-) >> you need to use '-smooth raw' for the canvas code to use the >> interpretation of bezier control points that your manual >> computation expects... >> if I use the following in your sample, all 3 curves agree: >> .c create line $path -fill yellow -smooth raw -splinesteps 16 - >> width 5 >> >> Cheers, >> >> Daniel >> >> -- >> ** Daniel A. Steffen Dept. of Mathematics ** >> ** Macquarie University NSW 2109 Australia ** >> >> > > > ---------------------------------------------------------------------- > --- > 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 > tc...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-mac > |
From: Daniel A. S. <st...@ma...> - 2007-03-20 09:15:27
|
On 20/03/2007, at 4:32, Revar Desmera wrote: > Interesting. The canvas man page I have installed on my system > doesn't mention 'raw' at all. c.f. TIP 168: http://tip.tcl.tk/168 http://rutherglen.ics.mq.edu.au/fisheye/changelog/Tk?cs=MAIN:dkf: 20040819144150 Cheers, Daniel -- ** Daniel A. Steffen Dept. of Mathematics ** ** Macquarie University NSW 2109 Australia ** |
From: Mats B. <ma...@pr...> - 2007-03-20 13:18:04
|
You could try my tkpath package where you get better control and can select either quadratic or cubic beziers and set explicit control points: http://tclbitprint.sourceforge.net/ http://tclbitprint.sourceforge.net/tkpath/quartz/index.html /Mats |
From: Robert K. <ro...@na...> - 2007-03-20 17:04:28
|
Sorry, but I don't build from scratch very often. I am trying to download and build latest 8.4 tcl and tk with this cvs command and am getting a compile error. Is the cvs command incorrect? cvs -z3 -d:pserver:ano...@tc...:/cvsroot/tcl co -r core-8-4-branch -P tcl make -C tcl/macosx clean make -C tcl/macosx ends with: no rule to make target '/Users/robert.........generic/tommath.h', needed by tclBasic.o. Stop. When I remove the -r core-8-4-branch I get the 8.5 version and it builds fine. Thanks for any help! RK |
From: Daniel A. S. <st...@ma...> - 2007-03-20 22:19:47
|
On 20/03/2007, at 19:18, Robert Karen wrote: > Sorry, but I don't build from scratch very often. > > I am trying to download and build latest 8.4 tcl and tk > with this cvs command and am getting a compile > error. Is the cvs command incorrect? > cvs -z3 -d:pserver:ano...@tc...:/cvsroot/tcl > co -r core-8-4-branch -P tcl > make -C tcl/macosx clean > make -C tcl/macosx > ends with: > no rule to make target '/Users/robert.........generic/tommath.h', > needed > by tclBasic.o. Stop. > > When I remove the -r core-8-4-branch I get the 8.5 version and it > builds > fine. that looks like something was left behind in your core-8-4-branch tree or build dir from an earlier HEAD checkout/build, there is no reference to tommath.h in any file in core-8-4-branch. I would suggest starting from scratch with a clean checkout of core-8-4-branch and an empty build dir... Cheers, Daniel -- ** Daniel A. Steffen Dept. of Mathematics ** ** Macquarie University NSW 2109 Australia ** |
From: Robert K. <ro...@na...> - 2007-03-21 21:30:55
|
Is it possible to run 'exec [info nameofexecutable] &' and have the new wish appear raised and have focus? raise commands didn't do it for me. Thanks, Robert Karen |
From: Jeff H. <je...@ac...> - 2007-03-21 22:29:26
|
Robert Karen wrote: > Is it possible to run 'exec [info nameofexecutable] &' and have the new > wish appear raised and have focus? raise commands didn't do it for me. OS X has some standard behaviors that prevent loss of focus in the currently executing application. Tk conversely doesn't seem to be very aggressive in saying "I've just started up". You can use the tclCarbonProcesses extension to force it to be the front process (setFrontProcess). -- Jeff Hobbs, The Tcl Guy, http://www.ActiveState.com/ |
From: Oscar B. <ob...@bi...> - 2007-03-29 18:55:40
|
Hi Robert, You need to apply this patch to Tk. Note however that this violates Apple's Human-Interface guidelines... #### ChangeSet #### 2006-07-21 10:45:55-07:00, ob...@di... Make Tk apps come up in the front instead of in the back when exec'ing Wish directly instead of using Launch Services to run the application. ==== macosx/tkMacOSXInit.c ==== 2006-07-21 10:45:54-07:00, ob...@di... +13 -0 Make Tk apps appear in the foreground even if not launched through LaunchServices. This breaks Aqua guidelines, but oh well. --- 1.21/macosx/tkMacOSXInit.c 2006-07-19 23:24:16 -07:00 +++ 1.22/macosx/tkMacOSXInit.c 2006-07-21 10:45:54 -07:00 @@ -255,6 +255,19 @@ TkpInit(interp) } } } +#ifdef MAC_OSX_WISH_COMES_UP_IN_FRONT + ProcessSerialNumber psn; + + /* Make sure the window comes up in the front of the calling + * application. The problem this solves is that if you exec + * the wish shell that is inside the application bundle, the + * new window appears _behind_ the calling application. + * We solve this by making Tk move its processID to the + * front of the Z-axis stacking order that the Window Server + * keeps. + */ + if (GetCurrentProcess(&psn) >= 0) SetFrontProcess(&psn); +#endif #if MAC_OSX_TK_USE_CPS_SPI /* * If we are loaded into an executable that is not a bundled application, On Mar 21, 2007, at 3:26 PM, Jeff Hobbs wrote: > Robert Karen wrote: >> Is it possible to run 'exec [info nameofexecutable] &' and have >> the new >> wish appear raised and have focus? raise commands didn't do it for >> me. > > OS X has some standard behaviors that prevent loss of focus in the > currently executing application. Tk conversely doesn't seem to be > very > aggressive in saying "I've just started up". You can use the > tclCarbonProcesses extension to force it to be the front process > (setFrontProcess). > > -- > Jeff Hobbs, The Tcl Guy, http://www.ActiveState.com/ > > ---------------------------------------------------------------------- > --- > 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 > tc...@li... > https://lists.sourceforge.net/lists/listinfo/tcl-mac -- pgp fingerprint: BC64 2E7A CAEF 39E1 9544 80CA F7D5 784D FB46 16C1 |
From: Revar D. <rev...@gm...> - 2007-03-20 19:40:04
|
Yeah, I was looking at that. It looks neat, and it'd definitely make some things easier for me, but so far I've managed to keep to pure TCL with no extensions used. Anyhow I'd like to thanks everyone for the very helpful comments! - Revar On Mar 20, 2007, at 6:18 AM, Mats Bengtsson wrote: > You could try my tkpath package where you get better control and > can select > either quadratic or cubic beziers and set explicit control points: > http://tclbitprint.sourceforge.net/ > http://tclbitprint.sourceforge.net/tkpath/quartz/index.html > > /Mats |