
madskool.wordpress.com
Here's a nice little problem. How do I draw an approximation for a circle using curveTo.
Not in the way that the flash MX documentation states  that's for sure!
I need a good value for the control point of each quarter segment. I could use trial and error to find an appoximation  but I want a mathematically derived value.
This is what I tried to do to find an answer. But it didn't work out:
Consider the first segment of a unit circle. The problem is to find a control point (q,q) to that the quadratic bezier approimates:
x1(t)=cos(t*PI/2)
y1(t)=sin(t*PI/2)
0<=t<=1
I assume the equations of the curve that curveTo draws in this case are:
x2(t,q)=q*t*(1t)+(1t)^2
y2(t,q)=q*t*(1t)+t^2
0<=t<=1
(Please correct this assumption if wrong)
So I assumed:
error=sqrt((x1(t)x2(t,q))^2+(y1(t)y2(t,q))^2)
I differentiated (d error / d q). Unfortunately, this didn't lead to a valid answer.
Any suggestions?

Hey brutfood!
I made an example based on 4 prototypes found here:
http://chattyfig.figleaf.com/flashco...CodeOnlyCircle
The first 3 are using 'curveTo', drawn in 45 degree increments ... all basically the same, with the first 2 by Casper Schuirink ... #2(CW) is the mirror of #1(CCW), used for masking purposes. The 3rd by Ralf Bokelberg is the same as #1, but he creates variables for use in the multiple 'curveTo' functions.The 4th by Tatsuo Kato uses 'lineTo' instead, with .01 increments through 2PI of the polar to Cartesian equation.
http://members.shaw.ca/flashmath101/bezierCircle.swf
http://members.shaw.ca/flashmath101/bezierCircle.fla
Richard

madskool.wordpress.com
Thanks
Thanks Richard,
FlashCoders looks an interesting community too. Any idea how Casper Schuirink arrived at his solution?

Here you go ... I hope you can follow the logic:
// circle quadrants... 1:NE, 2:NW, 3:SW, 4:SE
// anchor points use sin and cos: both values range from 1to1
// sin...quadrants 1 and 2 positive values, 3 and 4 negative values
// cos...quadrants 1 and 4 positive values, 2 and 3 negative values
// 0.7071 and 0.7071 are sin and cos values for pi/4 radians or 45 degrees, +/ depends on quadrant
// control points use tan and cot...quadrants 1 and 3 positive values, 2 and 4 negative values
// 0.4142 and 0.4142 are tan and cot values for pi/8 or 22.5 degrees, halfway through each 45 degree bezier angle
// tan used for xaxis +/ pi/8, cot used for yaxis +/ pi/8
// tan=sin/cos, cot=cos/sin
// note: there is no Flash Math.method for cotangent
// control points for 8 quadratic beziers of the circle are located at radius+ x or y offset and the complementary cos or sin value[/b]
Code:
MovieClip.prototype.drawCircle = function(r, x, y) {
// r=circle radius, x,y=offset circle center coordinates within mcClip
this.moveTo(x+r, y);
// start drawing circle CCW at positive xaxis, at distance r from center(x+r)
// 1st anchor point...x:(x+r), y:y
this.curveTo(r+x,0.4142*r+y,0.7071*r+x,0.7071*r+y);
// control point...x:radius+x offset, y:tan(pi/8)*radius+y offset
// 2nd anchor point...x:cos(pi/4)*radius+x offset, y:sin(pi/4)*radius+y offset
// becomes 1st anchor point for next curveTo
this.curveTo(0.4142*r+x,r+y,x,r+y);
// control point...x:cot(3pi/8)*radius+x offset, y:radius+ y offset
// 2nd anchor point...x:x offset,y:radius+y offset
// etc...
this.curveTo(0.4142*r+x,r+y,0.7071*r+x,0.7071*r+y);
this.curveTo(r+x,0.4142*r+y,r+x, y);
this.curveTo(r+x,0.4142*r+y,0.7071*r+x,0.7071*r+y);
this.curveTo(0.4142*r+x,r+y,x,r+y);
this.curveTo(0.4142*r+x,r+y,0.7071*r+x,0.7071*r+y);
this.curveTo(r+x,0.4142*r+y,r+x,y);
}// Casper Schuirink
http://members.shaw.ca/flashmath101/...nitCircle8.swf
BTW ... this isn't a perfect circle either, but it certainly is an improvement over the 90 degree quadratics used in the Flash help example. That's why using the cubic Bezier approximation algorithms of the beziers thread is such a good thing!
edit
I had the wrong version of unit circle up, which didn't show CCW degrees, nor unit circle radian equations. v8 isn't complete either (I never did get the trig graphing and angle functions finished...I must convert this all to Flash MX soon!), however degree values are now correct.
Richard
[Edited by Dickee on 09142002 at 07:22 PM]

madskool.wordpress.com
Doh!
Doh!
What obvious logic. Apologies for my stupid question. And for not recognising 0.707 as PI/4  I should be shot by my old maths teacher.
I was looking for better control points to make 4 curveTos look better  when I should just have increased the number of curvesTos to 8.
I like the FlashCoders solution also to drawing an elipse also  very useful.

Unexpected results
Hmmmm ... I made a file to compare the 845 degree segment quadBezier Circle from the post above with Timothee Groleau's 'drawCubicBezier' algorithm, in which I used 490 degree 'cubicBezier' segments to form the circle. Each 'cubicBezier' segment is produced by recursively drawing quadratic bezier 'curveTos' (default is 4 ... adjustable to 10), which produces a total of 1640 'curveTos' for the entire circle.
Now, assuming that the algorithm for 'kappa' by G. Adam Stanislav that I found here is correct, I expected the 'cubicBezier' algo (blue circle) to be more accurate than the 'quadBezier' algo (red circle). However, after about 5 rightclick 'zoomins', viewing the circle graphic (buttonpress 'n hold within the circle) at the perimeter reveals the 'quadBezier' algo to be more accurate, no matter what the 'cubicBezier's recurse' value is set to ... who knew!
quadcubicBezierCircle: .swf .zip
There is a very interesting thread called: 'Circle from Bezier Curve' at the [comp.graphics.algorithms] newsgroup which deals with this subject in detail.
In summation, circle precision relies more on the number of control points/segments than on the number of 'curveTos'. The 'cubicBezier' algo is still very useful, however, for drawing selfintersecting bezier curves, which can't be accomplished with a single quadratic bezier line.
Richard
Posting Permissions
 You may not post new threads
 You may not post replies
 You may not post attachments
 You may not edit your posts

Forum Rules

Click Here to Expand Forum to Full Width
