catmull rom spline

Dear All,

I am trying to render the Catmull Rom Spline curve. I generated the points using the Catmull Rom curve equation. But when I render these points, instead of curve, I am getting a straight line.

 


#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <stdio.h>


struct point
{
	float x;
	float y;
};




struct point CatmullRoll(float t, struct point p1, struct point p2, struct point p3, struct point p4)
{

	float t2 = t*t;
	float t3 = t*t*t;
	struct point v; // Interpolated point
		
	/* Catmull Rom spline Calculation */

	v.x = ((-t3 + 2*t2-t)*(p1.x) + (3*t3-5*t2+2)*(p2.x) + (-3*t3+4*t2+t)* (p3.x) + (t3-t2)*(p4.x))/2;
	v.y = ((-t3 + 2*t2-t)*(p1.y) + (3*t3-5*t2+2)*(p2.y) + (-3*t3+4*t2+t)* (p3.y) + (t3-t2)*(p4.y))/2;
	printf("Values of v.x = %f and v.y = %f
", v.x,v.y);

	return v;	
}

void initScene()                                                
{
	glClearColor(0.0,0.0,0.0,0.0);
	glShadeModel(GL_FLAT);
	glEnable(GL_POINT_SMOOTH);
	glEnable(GL_LINE_SMOOTH);
	glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);	// Make round points, not square points
	glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);		// Antialias the lines

}

/* void mouse(int button,)
{

*/
void reshape(int w,int h)
{
	glViewport(0,0,(GLsizei)w,(GLsizei)h);
	glMatrixMode(GL_PROJECTION);
	if(w<=h)
		glOrtho(-60.0,60.0,-60.0*(GLfloat)h/(GLfloat)w,60.0*(GLfloat)h/(GLfloat)w,-60.0,60.0);
	else
		glOrtho(-60.0,6.0,-60.0*(GLfloat)w/(GLfloat)h,60.0*(GLfloat)w/(GLfloat)h,-60.0,60.0);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();

}
void display(void)
{
	float t;
	struct point v;	//Interpolated point 
	struct point p1,p2,p3,p4,p5;

	p1.x  = -30.25;p1.y = -10.25;
	p2.x  = -40.5; p2.y  = -20.5;
	p3.x  =  45.33;p3.y = 5.33;
	p4.x  =  70.66;p4.y = 20.66;
	
	glClear(GL_COLOR_BUFFER_BIT);
	glColor3f(1.0f,1.0f,1.0f);
	glPointSize(8);

	glBegin(GL_POINTS);
		glVertex2f(p1.x,p1.y);
		glVertex2f(p2.x,p2.y);
		glVertex2f(p3.x,p3.y);
		glVertex2f(p4.x,p4.y);
	glEnd();

	for(t=0;t<1;t+=0.02)
	{
		v = CatmullRoll(t,p1,p2,p3,p4);
		glBegin(GL_POINTS);
			glVertex2f(v.x,v.y);
		glEnd();
	}
	glFlush();
                                                                                                                                                                                        
}


void main(int argc, char *argv[])
{
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
	glutInitWindowSize(500,500);
	glutInitWindowPosition(100,100);
	glutCreateWindow("Catmull Roll");
	initScene();
	glutDisplayFunc(display);	
	glutReshapeFunc(reshape);
	glutMainLoop();
}

                                                                                                                                                                                                        


 

Never mind, didnt read well enough…

I just noticed your glOrtho has x in [-60,6] if w > h (most often the case). Not sure that’s what you intended, but it might lead to unexpected results if it isn’t.

Also, it might be a good idea to load an identity on the projection matrix stack before you call Ortho. Otherwise, you’ll end up concatenating a projection matrix on the stack each time reshape is called.

Lastly, check your spline equation:

float CatmullRom( float u, float x0, float x1, float x2, float x3 )
{
    float u2 = u * u;
    float u3 = u2 * u;
    return ((2 * x1) + 
           (-x0 + x2) * u + 
           (2*x0 - 5*x1 + 4*x2 - x3) * u2 + 
           (-x0 + 3*x1 - 3*x2 + x3) * u3) * 0.5f;
}

Points on catmull rom splines with a value of t between 0 and 1 are interpolated between control points p1 and p2 and not extended to p0 and p4.

For more detailed information, have a look at http://www.mvps.org/directx/articles/catmull/

Greetz,

Nico

Out of curiosity, I tested your sample points, and the result does indeed look like a line. Try some different sample points; these produce a nice little wave-like curve:

float xy[4][2]=
{
    // x     y
    -90.0, +30.0,
    -30.0, -30.0,
    +30.0, +30.0,
    +90.0, -30.0
};