0% found this document useful (0 votes)
12 views6 pages

Drawing Parametric Curves and Splines

Uploaded by

fatmaserry16
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
12 views6 pages

Drawing Parametric Curves and Splines

Uploaded by

fatmaserry16
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 6

Computer Graphics Course Notes

Drawing Parametric Curves and Splines

Parametric curves are defined as vector functions of some scalar parameter t running from 0 to 1.
Mathematically, a point (x, y) on a curve is computed using two functions and of the parameter
t.

[ ] [ ]

The shape of the curve depends on the form of the functions and . For example if the two
nd
functions are linear in t, the curve is a line; if they are of 2 order degree, the curve is a quadratic
curve and so on.

Parametric lines:

The general form of parametric line equation is:

[ ] [ ]

To get the coefficients , we may constrain the line to pass through two end points:
when t=0 and when t=1. Substituting in the above equation yields:

[ ] [ ] [ ]

[ ] [ ] [ ]

From which we have four equations in four unknowns. Note that we can solve for using only
the two constrains involving x which are:

Getting:

So:

In the same way we get:

Note also that we don’t have to work on y; after all, the formula of y is the same as that of x except
that every x is replaced with y. This always happens when the two functions and have the same
form (of course with different coefficients in general). The equations can also be written as follows:

Prof. Reda A. El-Khoribi Page 1


Computer Graphics Course Notes

Here we notice that each of the end points is multiplied by a function of t that weighs its
contribution to the point at t. This function is called ‘basis function’ or ‘blending function’. Basis
functions for the line case are:

Cubic Hermite Curves

A third order (cubic) parametric curve is given by:

The derivatives with respect to t are:

Hermite curves use four constraints to compute the 4 coefficients of each function. We’ll derive the
coefficients of x(t) only because those of y(t) will follow a similar procedure. The constraints on x(t)
are:

Substituting in x(t) and x’(t):

In matrix form:

[ ][ ] [ ]

Prof. Reda A. El-Khoribi Page 2


Computer Graphics Course Notes

Solving for the coefficients:

[ ] [ ] [ ] [ ][ ]

Now we can write x(t) in a matrix form as follows:

[ ][ ]

So:

[ ][ ][ ]

This is equivalent to:

The matrix [ ] is called ‘basis matrix’. If it is left-multiplied by the raw vector

[ ] the result is a raw vector with Hermite’s basis (blending) functions:

[ ]

There’s many ways to compute x(t). The efficient way is to use the matrix form and start by right-
multiplying the basis matrix by the input vector before the loop.

In Visual C++, we may build matrix and vector classes or structures to use them in the
implementation (we’ll need them also when we talk about transformation in next lectures).

struct Vector2
{
double x,y;
Vector2(double a=0,double b=0)
{
x=a; y=b;
}
};
class Vector4
{
double v[4];
public:
Vector4(double a=0,double b=0,double c=0,double d=0)
{
v[0]=a; v[1]=b; v[2]=c; v[3]=d;
}

Prof. Reda A. El-Khoribi Page 3


Computer Graphics Course Notes
Vector4(double a[])
{
memcpy(v,a,4*sizeof(double));
}
double& operator[](int i)
{
return v[i];
}
};
class Matrix4
{
Vector4 M[4];
public:
Matrix4(double A[])
{
memcpy(M,A,16*sizeof(double));
}
Vector4& operator[](int i)
{
return M[i];
}
};
The following Matrix and Vector utility functions are also useful in our implementation

Vector4 operator*(Matrix4 M,Vector4& b) // right multiplication of M by b


{
Vector4 res;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
res[i]+=M[i][j]*b[j];
return res;
}

double DotProduct(Vector4& a,Vector4& b) //multiplying a raw vector by a column vector


{
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
}
The implementation of the Hermite curve uses the following utility function to compute the
coefficients and store them in a 4D vector.

Vector4 GetHermiteCoeff(double x0,double s0,double x1,double s1)


{
static double H[16]={2,1,-2,1,-3,-2,3,-1,0,1,0,0,1,0,0,0};
static Matrix4 basis(H);
Vector4 v(x0,s0,x1,s1);
return basis*v;
}
The main Hermite curve drawing is thus implemented as:

void DrawHermiteCurve(HDC hdc,Vector2& P0,Vector2& T0,Vector2& P1,Vector2& T1 ,int


numpoints, COLORREF color)
{
Vector4 xcoeff=GetHermiteCoeff(P0.x,T0.x,P1.x,T1.x);
Vector4 ycoeff=GetHermiteCoeff(P0.y,T0.y,P1.y,T1.y);
if(numpoints<2)return;
double dt=1.0/(numpoints-1);
for(double t=0;t<=1;t+=dt)
{
Vector4 vt;
vt[3]=1;

Prof. Reda A. El-Khoribi Page 4


Computer Graphics Course Notes
for(int i=2;i>=0;i--)vt[i]=vt[i+1]*t;
int x=round(DotProduct(xcoeff,vt));
int y=round(DotProduct(xcoeff,vt));
SetPixel(hdc,x,y,color);
}
}
The algorithm uses the parameter ‘numpoints’, that means number of points sampled from the
curve function, to compute the step by which t increases in the loop. Note that it is better to use the
line drawing function instead of SetPixel in order to guarantee the connectivity of the curve. Here is
the implementation using the Windows API functions of line drawing: MoveToEx and LineTo:

void DrawHermiteCurve (HDC hdc,Vector2& P0,Vector2& T0,Vector2& P1,Vector2& T1 ,int


numpoints)
{
Vector4 xcoeff=GetHermiteCoeff(P0.x,T0.x,P1.x,T1.x);
Vector4 ycoeff=GetHermiteCoeff(P0.y,T0.y,P1.y,T1.y);
if(numpoints<2)return;
double dt=1.0/(numpoints-1);
for(double t=0;t<=1;t+=dt)
{
Vector4 vt;
vt[3]=1;
for(int i=2;i>=0;i--)vt[i]=vt[i+1]*t;
int x=round(DotProduct(xcoeff,vt));
int y=round(DotProduct(ycoeff,vt));
if(t==0)MoveToEx(hdc,x,y,NULL);else LineTo(hdc,x,y);
}
}
The problem with the Hermite curve algorithm is the interpretation of the tangent (derivative)
vectors T0 and T1. In computer animation it may be used to represent the velocity of the moving
object at t=0 and t=1 respectively while P0 and P1 represent the position of the moving object at t=0
and t=1. The algorithm in this case is used to interpolate the motion of the object at values of t
between 0 and 1. This means that t is a scaled version of the time during which the animation takes
place. In curve drawing applications however, it is difficult for the designer to decide the correct
values of T0 and T1 for some specific curve.

Bezier Curves

Bezier curves are special cases of Hermit curves in which T0 and T1 are computed from four points P0,
P1, P2, P3 as follows:

The curve starts at P0 when t=0 and ends at P3 when t=1. This has a geometrical interpretation if we
consider the individual components of the four points for example the x components i.e. x0, x1, x2, x3.
Bezier assumes that x=x0 when t=0, x=x1 when t=1/3, x=x2 when t=2/3 and x=x3 when t=1. So we
have four points in the T-X plane: (0, x0), (1/3, x1), (2/3, x2) and (1, x3). The line connecting the point
(0, x0) to (1/3, x1) is tangent to the curve at t=0 so equals the slope of this line; i.e.:

Prof. Reda A. El-Khoribi Page 5


Computer Graphics Course Notes

Likewise, the line connecting (2/3, x2) to (1, x3) is tangent to the curve at t=1 so equals the
slope of the line at t=1; i.e.

The curve will not pass through P1 and P2. It lies in the ‘convex hull’ of the polygon P0-P1-P2-P3. The
following is an implementation of Bezier curve that calls the Hermite curve algorithm:

void DrawBezierCurve(HDC hdc,Vector2& P0,Vector2& P1,Vector2& P2,Vector2& P3,int


numpoints)
{
Vector2 T0(3*(P1.x-P0.x),3*(P1.y-P0.y));
Vector2 T1(3*(P3.x-P2.x),3*(P3.y-P2.y));
DrawHermiteCurve(hdc,P0,T0,P3,T1,numpoints);
}

Cardinal splines

If we are given a set of points P0, P1, P2, …, Pn, we can draw a curve passing through P1, P2,…,Pn-1 by
calling the Hermite curve drawing algorithm for every interval Pi-Pi+1 , i=1,2,..,n-2. The slope at Pi is
given by:

c is called the ‘tension’ of the curve that takes values from 0 to 1. The following function shows the
implementation of this algorithm. Note that the algorithm does not draw the first and last interval
because it cannot compute the tangents at these points.

void DrawCardinalSpline(HDC hdc,Vector2 P[],int n,double c,int numpix)


{
double c1=1-c;
Vector2 T0(c1*(P[2].x-P[0].x),c1*(P[2].y-P[0].y));
for(int i=2;i<n-1;i++)
{
Vector2 T1(c1*(P[i+1].x-P[i-1].x),c1*(P[i+1].y-P[i-1].y));
DrawHermiteCurve(hdc,P[i-1],T0,P[i],T1,numpix);
T0=T1;
}
}

Prof. Reda A. El-Khoribi Page 6

You might also like