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