Click here to Skip to main content
15,890,897 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I would like to draw a 3 point parametric spline as demonstrated at this webpage. This is not a bezier curve. The points must all be on the curve.

"http://www.doc.ic.ac.uk/~dfg/AndysSplineTutorial/Parametrics.html"

I need two simultanious equations, x and y with a common variable(t = 0-1). Don't know how to create them from the mathematics. Any help would be appreciated. thanks.
Posted
Updated 17-Apr-13 6:59am
v2

It is quite simple: the equation (the page you linked) provided is vectorial, let's write it (for simplicity)
P(0)={x0,y0}={a0,b0};
P(s)={xs,ys}={a2*s*s+a1*s+a0, b2*s*s+b1*s+b0}
P(1)={x1,y1}={a2+a1+a0, b2+b1+b0}

Where the P(0), P(s), P(1) are known (0<s<1).
We have to find the six parameters a2,a1,a0, b2,b1,b0. Limiting computation to x (y is the same):
x0 = a0
x1 = a2+a1+x0 => a1 = x1-x0-a2
xs = a2*s*s+x1*s-x0*s-a2*s+x0 => a2 = (xs-x0+(x0-x1)*s)/(s-s*s)

With a2 value you compute a1 using the second equation.
Now a2,a1,a0 (and in the same way b2,b1,b0) are known and you may compute P(t) = {x(t), y(t)} = {a2*t*t+a1*t+a0, b2*t*t+b1*t+b0} for each 0<t<1.
(I hope it is correct...)
 
Share this answer
 
Some formulas in the referenced web site are not correct. Especially the result formula for a1 is wrong.

You must understand that you have the freedom to chose the t1 for your P1: by varying t1 for your chosen P1, the shape of the curve will vary too.

Assuming you have three defined points:
- start (t = 0) at P0
- end (t = 1) at P2
- a point P1 between start and end where you also decide for a t1 (e.g. 0.5).

Given these four parameters (P0, P2, P1, t1), the needed curve coefficients are:
a0 = A
a1 = B - t1 C
a2 = C - B
Where
A = P0
B = (P1 - P0) / ((1 - t1) t1)
C = (P2 - P0) / (1 - t1)

If working in 2D, each coefficient consists of two values, one for each axis - working in 3D, each coefficient consists of 3 values, on per axis.

E.g. for each axis coeficient value, you set the respective axis value of the points Pu plus the parameter t1 value into the formulas above.

Then you sweep the parameter t from 0 to 1 and calculate the curve points P(t) to draw.

pseudo code:
C#
class Formula
{
    private Point a0;
    private Point a1;
    private Point a2;

    private Point A(Point p0, Point p1, Point p2, double t1) { return p0; }
    private Point B(Point p0, Point p1, Point p2, double t1) { double d = 1/((1-t1)*t1); return (p1-p0)*d; }
    private Point C(Point p0, Point p1, Point p2, double t1) { return d = 1/(1-t1); return (p2-p0)*d; }

    public Formula(Point p0, Point p1, point p2, double t1)
    {
       Point a = A(p0, p1, p2, t1);
       Point b = B(p0, p1, p2, t1);
       Point c = C(p0, p1, p2, t1);

       a0 = a;
       a1 = b-c*t1;
       a2 = c-b;
    }
    public Point P(double t) { return ((a2*t)+a1)*t+a0; }
}
...
var start = new Point(0,2); // p0
var end   = new Point(7,6); // p2
var p1    = new Point(2,3); // p1
double t1 = 0.5;
var Formula curve = new Formula(start, p1, end, t1);
...
int steps = 100;
double step = 1.0/(double)steps;
Point curr = p0;
foreach(int i = 1; i <= steps; ++i)
{
   Point next = curve.P(step*(double)i);
   Draw(curr, next);
   curr = next;
}


Cheers
Andi
 
Share this answer
 
v2
C#
private void DrawCurve( Graphics g, PointF a, PointF b, PointF c )
        {
            float t, n = 30;

            float x1 = 4 * b.X - 2 * ( a.X + c.X );
            float x2 = x1 - a.X + c.X;
            float y1 = 4 * b.Y - 2 * ( a.Y + c.Y );
            float y2 = y1 - a.Y + c.Y;

            PointF p1 = a, p2;

            for( float i = 1; i <= n; i++ )
            {
                t = i / n;
                p2 = new PointF( a.X - x1 * t * t + x2 * t, a.Y - y1 * t * t + y2 * t );
                g.DrawLine( pen, p1, p2 );
                p1 = p2;
            }
        }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900