Home > Uncategorized > Late night splining

Late night splining

I love coding, I really do. I’m not saying I want to spend the rest of my life writing code but there is something cathartic about the process. Our lives are filled with so many instabilities that it is nice to sit down w/ a system based purely on logic and know that following the rules will lead to an expected result.

Some posts back I made a reference to catmull-rom splines but the code was messed up during the copy process to the blog. Here today I’m going to attach a single .cpp file that will create a spline and render it in OpenGL. Easy right?

Splines.cpp

95% of this code is NeHe’s wonderfully simplistic OpenGL tutorial. That’s how little code it takes to spline. Given that it is 3:30am. you’ll have to forgive my lack of comments in the Spline.cpp file. But these should suffice:

 
 
///catmull-rom spline (t should range from 0-1)
double catmullrom(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));
}
 
///create a dummy point vector, points here are chosen @ random
void FillPointVector(){
	pointList.push_back(vector3(-500,700,10));
	pointList.push_back(vector3(-300,12,10));
	pointList.push_back(vector3(-300,12,10));
	pointList.push_back(vector3(-100,12,10));
	pointList.push_back(vector3(-50,45,0));
	pointList.push_back(vector3(0,0,20));
	pointList.push_back(vector3(50,0,15));
	pointList.push_back(vector3(200,350,30));
	pointList.push_back(vector3(350,0,20));
	pointList.push_back(vector3(356,35,60));
	pointList.push_back(vector3(400,67,15));
	pointList.push_back(vector3(424,122,0));
	pointList.push_back(vector3(450,1,0));
	pointList.push_back(vector3(500,0,0));
}
 
///Build full path;
void BuildPath(){
	FillPointVector();
 
	printf("Point vector filled: %d\n",pointList.size());
	float granularity = 0.1f;  // This refers to the step size between points along a spline.
	printf("Filled line list...");
 
	for(int c = 0; c < pointList.size()-3; c++){
		vector3 p0,p1,p2,p3;
		p0 = pointList[c];
		p1 = pointList[c+1];
		p2 = pointList[c+2];
		p3 = pointList[c+3];
		for(float i = 0; i <= 1; i+=granularity){
			vector3 pt;
			pt.x = catmullrom(i,p0.x,p1.x,p2.x,p3.x);
			pt.y = catmullrom(i,p0.y,p1.y,p2.y,p3.y);
			pt.z = catmullrom(i,p0.z,p1.z,p2.z,p3.z);
 
                        ///ignore this crap
			if(i==0){
				minPt = maxPt = pt;
			} else {
				minPt = vector3::Min(minPt,pt);
				maxPt = vector3::Max(maxPt,pt);
			}
			lineList.push_back(pt);
		}
		printf(".");
	}
	printf("Complete[%d]\n",lineList.size());
 
	printf("Sample: %f %f %f\n",lineList[0].x,lineList[0].y,lineList[0].z);
 
        //make sure line list is EVEN or we'll run in to problems w/ OpenGL.
        if(lineList.size() % 2 != 1 && lineList.size() != 0)lineList.pop_back();
}

Take note that splines are made up of 4 control points and we merge these to form one cohesive path.

Categories: Uncategorized Tags:
  1. No comments yet.
  1. No trackbacks yet.