Cardinal Splines in GDI Plus
Tue, 11 Mar 2008 22:09:43 -0400 - Author:
A cardinal spline is one way to draw curves on a computer screen. This function I wrote today and tested is a rewrite of the DrawCurve/DrawClosedCurve method that draws cardinal splines with cubic Bézier curves supported by many graphics packages.
public static void DrawCurve(Graphics g, PointF[] pts, double tension, bool closefigure){
int i;
double x0,x1,y0,y1;
int numpoints=pts.Length;
tension/=3;
for(i=0;i<numpoints;i++){
int prev=i-1;
int thispt=i;
int next1=i+1;
int next2=i+2;
if(thispt==0 && closefigure)
prev=numpoints-1;
if(thispt==numpoints-2 && closefigure)
next2=0;
if(thispt==numpoints-1){
if(!closefigure)break;
next1=0;
next2=1;
}
if(prev<0){
// At start of curve
ASSERT(thispt==0);
x0=pts[thispt].X+(pts[next1].X-pts[thispt].X)*tension;
y0=pts[thispt].Y+(pts[next1].Y-pts[thispt].Y)*tension;
} else {
x0=pts[thispt].X+(pts[next1].X-pts[prev].X)*tension;
y0=pts[thispt].Y+(pts[next1].Y-pts[prev].Y)*tension;
}
if(next2>=numpoints){
// At end of curve
x1=pts[next1].X+(pts[thispt].X-pts[next1].X)*tension;
y1=pts[next1].Y+(pts[thispt].Y-pts[next1].Y)*tension;
} else {
x1=pts[next1].X-(pts[next2].X-pts[thispt].X)*tension;
y1=pts[next1].Y-(pts[next2].Y-pts[thispt].Y)*tension;
}
g.DrawBezier(Pens.Black,(float)pts[thispt].X,(float)pts[thispt].Y,
(float)x0,(float)y0,(float)x1,(float)y1,(float)pts[next1].X,(float)pts[next1].Y);
}
}
