Home > Uncategorized > catmull-rom spline

catmull-rom spline

As a part of a class project I’m adding in the ability to animate along a catmull-rom spline. If you want to compile this code you’ll need to download my 3DIO library or simply create your own simplistic vector3 class. All it needs are 3 floats. You’ll also need the handy-dandy CImg library.

#include <3DIO/3DIO.h>
#include 
#include 
 
using namespace tdio_library;
using namespace std;
using namespace cimg_library;
 
double calc_cat(double t, double p0,double p1,double p2,double p3){
	double t2 = t*t;
	double t3 = t2 * t;
	return (0.5 *(    	(2 * p1) + (-p0 + p2) * t +(2*p0 - 5*p1 + 4*p2 - p3) * t2 +(-p0 + 3*p1- 3*p2 + p3) * t3));
}
 
void interactive_catmull(){
	vector control_pts;				///control point vector
	vector draw_pts;					///draw point vector
 
	CImg image(500,400,1,3,0);	///main image
	unsigned char red[] = {255,0,0};			///color red
 
	image.fill(0);
	CImgDisplay main_disp(image,"Click a point");
	int lastPt = 0;
 
	while (!main_disp.is_closed) {
		main_disp.wait();
		if (main_disp.button && main_disp.mouse_y>=0) {
			const int y = main_disp.mouse_y;
			const int x = main_disp.mouse_x;
			control_pts.push_back(vector3(x,y,0));
			if(lastPt + 4 <= control_pts.size()){
				draw_pts.clear();
				vector3 p0,p1,p2,p3;
				p0 = control_pts[lastPt];
				p1 = control_pts[lastPt+1];
				p2 = control_pts[lastPt+2];
				p3 = control_pts[lastPt+3];
 
				///We have enough pts(4 <= N <= INF)
				for(float i = 0; i <= 1; i+=0.01){
					vector3 pt;
					pt.x = calc_cat(i,p0.x,p1.x,p2.x,p3.x);
					pt.y = calc_cat(i,p0.y,p1.y,p2.y,p3.y);
					pt.z = calc_cat(i,p0.z,p1.z,p2.z,p3.z);
					draw_pts.push_back(pt);
				}
				for(int i = 0; i < draw_pts.size()-1; i++){
					image.draw_line((int)draw_pts[i].x,(int)draw_pts[i].y,(int)draw_pts[i+1].x,(int)draw_pts[i+1].y,red);
				}
				lastPt++;
			}
			image.draw_circle(x,y,2,red);
		}
		main_disp.display(image);
	}
}

Keep in mine you need 4 control points to define a curve and the curve is only drawn between Pt[1] and Pt[2] of each segment. This page has a nice graph and explanation.

Categories: Uncategorized Tags: