1

I was writing code to approximate a quarter ellipse to a Bézier curve.

Now having done that, I am encountering trouble drawing sections of this curve. I need some help choosing the control points.

Initially, I had taken the ratio of distance of control point to distance of start of curve as 0.51.

Edited:

pseudo code
import cairo [...]
ctx.moveto(0,y1)
ctx.curveto(0,y1/2,x1/2,0,x1,0)

This will result in an approximately elliptical curve from (0,y1) to (x1,0) with the ellipse center at (x1,y1).

Notice the parametric angle swept is pi/2. If suppose I wish to draw it in sections more like a dashed pattern, then how do I do it? For example, from t = pi/6 to t = pi/3? How do I choose the control points?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anil Shanbhag
  • 950
  • 1
  • 13
  • 31
  • 2
    Could you share us a cut-down version of your current code? –  Jun 05 '11 at 16:39
  • 1
    Please define "encountering trouble". What is the *specific* problem? – Oliver Charlesworth Jun 05 '11 at 16:39
  • The way your question is worded violates all the fundamental principles of asking good questions. Please read http://stackoverflow.com/questions/how-to-ask – Jim Garrison Jun 05 '11 at 16:41
  • Ok i violated "Be specific" : my apologies . Edit fixes up most part of it . – Anil Shanbhag Jun 05 '11 at 16:48
  • I don't think the question was unclear... what is asked was how to approximate a generic section of an ellipse using cubic bezier arcs. Somehow I've the impression that questions that are not trivial tend to be archived as "not a real question" when indeed they should be archived as "not a question that I know how to answer to, therefore not an interesting question". – 6502 Jun 06 '11 at 06:07
  • @6502: I don't think that is the question being asked. The OP wants to know how to generate sections of a bezier curve which just happens to be his approximation of quarter ellipse (not a circle, btw). – martineau Jun 06 '11 at 12:54
  • @martineau: He found how to draw a quarter ellipse but not a law about how to get control points for a generic part of the arc (i.e. the problem of approximating a generic circle arc). About the circle/ellipse distinction please note that an ellipse is a stretched circle and stretching a Bezier curve is trivial (just stretch the control points). Like I said in my answer this is not 100% mathematically correct (like it's not correct to say that the best arc interpolate the middle point) but if the approximation of the circle arc is acceptable the probably also the one for the ellipse will be. – 6502 Jun 06 '11 at 13:19

3 Answers3

5

To approximate a circle quarter using a single cubic arc what is normally done is making the middle point being exactly on the circle and using tangent starting and ending directions.

This is not formally the "best" approximation in any reasonable metric but is very easy to compute... for example the magic number for a circle quarter is 0.5522847498. See this page for some detail...

To draw an ellipse arc instead you can just stretch the control points of the circular arc (once again not something that would qualify mathematically as "best approximation").

The generic angle case

The best arc for a generic angle under this definition (i.e. having the middle point of the bezier being on the middle of the arc) can be computed using the following method...

1. The maximum height of a symmetrical cubic bezier arc is 3/4 H where H is the height of the control point

This should be clear considering how the middle point of a bezier cubic is computed with the De Casteljau's algorithm or my answer about explicit computation of a bezier curve; see also the following picture:

Height of midpoint of a symmetric Bezier cubic arc

y_mid = ((0+H)/2 + (H+H)/2) / 2 = 3/4 H


2. The angle at the center for a circle cord is twice the angle at the base

See any elementary geometry text for a proof.


Finally naming L the distance between the extremes, S the (unknown) control arm of the symmetric Bezier, 2*alpha the angle of circle to approximate we can compute that

3. S = L (2/3) (1-cos(alpha)) / (sin(alpha)**2)

This follows from the above equations and from some computation; see the following picture for a description.

Control point distance computation

Community
  • 1
  • 1
6502
  • 112,025
  • 15
  • 165
  • 265
1

I think you should use the control points of the whole curve. One way to do this would be to determine a parametric equation version of bezier -- see How to find the mathematical function defining a bezier curve.

Next, figure out what part of 0 <= t <= 1 in the parametric equation the section defined by the angle p1/6 <= ө <= pi/3 represents and then run that range of values through it.

There are ways of computing each point along some kinds of parametrically-defined curves which is applicable here and ought to make the drawing of a dashed pattern fairly straight forward and fast.

Community
  • 1
  • 1
martineau
  • 119,623
  • 25
  • 170
  • 301
  • Hmm i just tried a small experiment draw ellipse , draw from start to certain point . It doesnt work taking same control points as original. – Anil Shanbhag Jun 05 '11 at 19:31
  • Not sure what you mean by "It doesn't work". Seems as though you'd need to use the same control points in order to be generating points along sections of the same curve. – martineau Jun 06 '11 at 12:44
0

This Link has a good explanation of Bezier Curves. It goes over the basic math principles, and also provides sample code.

Because Bezier Curves are typically implemented using a parametric equation, you can just draw line segments between each sample point. Your step size will affect the smoothness of your curve if you draw them in this way.

dudeski
  • 141
  • 1
  • 2