PDA

View Full Version : Calculate points in an arc



jdarling
20-05-2010, 04:36 PM
I have 3 points, the start (P1), the mid (C) of what would be the ellipse, and the end point (P2). I know that I want to calculate n points along this arc. What is the best way of doing this?

Here is a picture in hopes that it helps:
http://www.eonclash.com/PGD/arc.png

Here is my basic prototype (note, vector elements are floats):

function CalcArc(const vStart, vEnd, vCenter : IVector; const numSteps : LongInt = 10) : TVectorArray;
begin
// What goes here???
end;

// Quick example:
procedure TestCalcArc;
var
arcPoints : TVectorArray;
i : LongInt;
begin
arcPoints := CalcArc(Vector(90, 0), Vector(100, 10), Vector(90, 10));
for i := low(arcPoints) to high(arcPoints) do
writeln(format('Point %d) %f, %f', [i, arcPoints[i].x, , arcPoints[i].y]));
end;


Any help greatly appreciated. I know some place in my collection I have this, but I'll be dogged if I can find it. And searching Google returns results related mainly to calculation surface area, lengths, or all points in an arc :(. Then again, my GoogleFoo isn't very strong.

- Jeremy

Traveler
20-05-2010, 06:53 PM
Perhaps this (http://www.tonypa.pri.ee/vectors/tut12.html) page is of some help to you?

tpascal
20-05-2010, 08:54 PM
Powerfull and flexible way is using bezier curves,

"Quadratic" bezier is a curve done using 3 points just like in your example,
"cubic" bezier is a curve done using 4 points.



function Calculate_Quadratic_Bezier(A, B, C: taffinevector; T: Single): taffinevector;
var
Sn : single;
begin
t:=1-t;
Sn:=1-t;
result.X := A.x*t*t + B.x*2*t*Sn + C.x*sn*sn;
result.Y := A.y*t*t + B.y*2*t*Sn + C.y*sn*sn;
result.Z := A.z*t*t + B.z*2*t*Sn + C.z*sn*sn;
end;

function Calculate_Cubic_Bezier(A, B, C, D: taffinevector; T: Single): taffinevector;
var
Sn : single;
begin
t:=1-t;
Sn:=1-t;
result.X := A.x*t*t*t + B.x*3*t*t*Sn + C.x*3*t*Sn*Sn + D.x*Sn*Sn*Sn;
result.Y := A.y*t*t*t + B.y*3*t*t*Sn + C.y*3*t*Sn*Sn + D.y*Sn*Sn*Sn;
result.Z := A.z*t*t*t + B.z*3*t*t*Sn + C.z*3*t*Sn*Sn + D.z*Sn*Sn*Sn;
end;



That also works for 2d points, just ignore Z component.

The "T" parameter is a value between 0..1 that allow you to calc the next point coordinate in the curve as much points you want in your curve, for example if you want to use 100 points for draw your curve then calc each point position using t values from 0.01 to 1.00; if you want to draw a curve with lets say 20 points then you do somthing like f:=1/20 and then use f as a factor into a 20 step loop for calc the points.

Full explanation with awesome animations can be found here:

http://en.wikipedia.org/wiki/B%C3%A9zier_curve

jdarling
21-05-2010, 03:00 PM
I hadn't thought about using Beziers, thanks for the idea, worked a charm :).

I knew I had something, just didn't know what it was (implied sarcasm in the I part LOL).

- Jeremy