Draw a smooth curve through a set of 2D points with Cubic Spline

With my yesterday post "Approximate cubic polynomial with polyline" it’s easy to draw the curve through the set of points with the aid of Cubic Spline interpolation.

After calculating Cubic Spline we have to approximate each partial cubic polynomial comprising the spline with the polyline, like this:

/// 
/// Approximate the spline with the PolyLine with the tolerance given.
/// 
/// The spline.
/// The tolerance, i.e. the maximum distance from the spline
///		to the approximating polyline.
/// List of points of the PolyLine approximating the spline 
///		with the tolerance given.
static List GetSplinePolyLineApproximation(Spline spline, double tolerance)
{
	List points = new List();
	points.Add(spline.Points[0]);
	// Loop by the spline subintervals.
	for (int i = 1; i < spline.Points.Length; ++i)
	{
		Collection cpPoints = GetApproximation(spline.Points[i - 1], spline.Points[i]
			, spline.SecondDerivative[i - 1], spline.SecondDerivative[i], tolerance);
		// Copy points but the first one.
		for (int j = 1; j < cpPoints.Count; ++j)
		{
			points.Add(cpPoints[j]);
		}
	}
	return points;
}

/// 
/// Approximate the cubic polynomial with the PolyLine with the tolerance given.
/// 
/// Cubic polynomial left point.
/// Cubic polynomial right point.
/// Cubic polynomial second derivative at the left point.
/// Cubic polynomial second derivative at the right point.
/// The tolerance, i.e. the maximum distance from the spline
///		to the approximating polyline.
/// List of points of the PolyLine approximating the cubic 
///		polynomial with the tolerance given.
static Collection GetApproximation(Point pt1, Point pt2, double y21, double y22, double tolerance)
{
	double x1 = pt1.X, x2 = pt2.X;
	double y1 = pt1.Y, y2 = pt2.Y;

	// Subinterval polynomial coefficients.
	double a = (y22 - y21) / (6 * (x2 - x1));
	double b = (y21 - 6 * a * x1) / 2;
	double c = (y2 - x2 * x2 * (a * x2 + b) - y1 + x1 * x1 * (a * x1 + b)) / (x2 - x1);
	double d = y1 - x1 * (x1 * (a * x1 + b) + c);
	if (a == 0)
		a = double.Epsilon;

	return ovp.CubicPolynomialPolylineApproximation.Approximate(
                new Polynomial(new double[] { d, c, b, a}), x1, x2, tolerance);
}

You can download the code sample here:

http://cid-39d56f0c7a08d703.skydrive.live.com/embedrowdetail.aspx/.Public/CubicSpline

It is Visual Studio 2008 solution targeted to .NET 3.5. It contains WPF Windows Application project designed to demonstrate drawing of some functions. You can select one of the curves from Combo Box at the top of the Window, experiment with point count and with tolerance and set appropriate XY Scales.

Advertisements

About ovpwp

I am engaged in programming, maintenance and supply of computing technique since 1970. Started with the computers M, BESM, Minsk series and received appropriate education in the least, in which it was then possible in THE USSR. Then he went the usual way - ES series, IBM 360/370, Sun Spark, Ibm Power & PS2, PC. Programming started in the code (machine commands), then were sorts of assemblers, Algol, FORTRAN, PL/1, C, C , VB, C#. It is only the ones that I used the production scale; but there were, of course, others like List, Modula, Pascal, Java, etc. Currently I prefer .NET platform for desktop development. I don't really like web-programming (probably because of the inability for quality design), but I have enough experience in site building in LAMP environment using PHP.
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s