nurbs and opennurbs, part 1.
our first attempt at using nurbs, needless to say we got in a little over our heads.. we used CGAL again.

see our pretty code behind the cut.
#include#include #include #include #include #include #include #include #include #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Partition_traits_2
Traits; typedef CGAL::Is_convex_2 Is_convex_2; typedef Traits::Polygon_2 Polygon_2; typedef Traits::Point_2 Point_2; typedef Polygon_2::Vertex_const_iterator Vertex_iterator; typedef std::list Polygon_list; typedef CGAL::Partition_is_valid_traits_2 Validity_traits; typedef CGAL::Creator_uniform_2 Creator; typedef CGAL::Random_points_in_square_2 Point_generator; #include "ofMain.h" #include "ofCvMain.h" #include #define NOTE_NUM 240 float g_Points1[7][3] = { { 600, 100, 0 }, { 450, 150, 2 }, { 150, 250, 0 }, { 50, 350, -2 }, { 120, 450, 0 }, { 280, 450, 2 }, { 80, 210, 0 } }; float g_Points2[7][3] = { { 80, 100, 0 }, { 280, 150, 2 }, { 120, 250, 0 }, { 50, 350, -2 }, { 150, 450, 0 }, { 450, 450, 2 }, { 600, 210, 0 } }; float g_Knots[] = {0.0f,0.0f,0.0f,0.0f,1.0f,2.0f,3.0f,4.0f,4.0f,4.0f,4.0f}; static void beginCallback(GLenum type) {} static void vertexCallback(GLfloat* vertex) {} static void normalCallback(GLfloat* vertex) {} static void endCallback() {} class world : public ofSimpleApp { public: void setup(); void update(); void draw(); void keyPressed( int key ); void mouseMoved( int x, int y ); void mouseDragged( int x, int y, int button ); void mousePressed( int x, int y, int button ); void mouseReleased(); void drawCurve(); void GetOutpoint(float t,float OutPoint[], float knots[], float cvs[7][3]); float CoxDeBoor(float u,int i,int k,const float* Knots); //NURBS unsigned int g_num_cvs; unsigned int g_degree; unsigned int g_order; unsigned int g_num_knots; unsigned int LOD; }; void world::setup() { ofSetFrameRate( 60 ); ofSetVerticalSync( true ); ofEnableAlphaBlending(); //NURBS g_num_cvs = 7; g_degree = 3; g_order = g_degree+1; g_num_knots = g_num_cvs+g_order; LOD = 20; } void world::update() { ofBackground( 100, 100, 100 ); } void world::draw() { ofSetColor( 0xffffff ); drawCurve(); } void world::drawCurve() { std::vector poc1; std::vector poc2; for(int i=0;i!=LOD;++i) { float t = g_Knots[g_num_knots-1] * i / (float)(LOD-1); if(i==LOD-1) { t-=0.001f; } float Outpoint[3]={0,0,0}; GetOutpoint(t, Outpoint, g_Knots, g_Points1); poc1.push_back(Outpoint[0]); poc1.push_back(Outpoint[1]); poc1.push_back(Outpoint[2]); } for(int i=0;i!=LOD;++i) { float t = g_Knots[g_num_knots-1] * i / (float)(LOD-1); if(i==LOD-1) { t-=0.001f; } float Outpoint[3]={0,0,0}; GetOutpoint(t, Outpoint, g_Knots, g_Points2); poc2.push_back(Outpoint[0]); poc2.push_back(Outpoint[1]); poc2.push_back(Outpoint[2]); } glColor3f(1, 0, 1); glBegin(GL_LINE_STRIP); for (int i=0; i 0.001f ) { OutPoint[0] += Val * cvs[i][0]; OutPoint[1] += Val * cvs[i][1]; OutPoint[2] += Val * cvs[i][2]; } } } float world::CoxDeBoor(float u, int i, int k, const float* Knots) { if(k==1) { if( Knots[i] <= u && u <= Knots[i+1] ) { return 1.0f; } return 0.0f; } float Den1 = Knots[i+k-1] - Knots[i]; float Den2 = Knots[i+k] - Knots[i+1]; float Eq1=0,Eq2=0; if(Den1>0) { Eq1 = ((u-Knots[i]) / Den1) * CoxDeBoor(u,i,k-1,Knots); } if(Den2>0) { Eq2 = (Knots[i+k]-u) / Den2 * CoxDeBoor(u,i+1,k-1,Knots); } return Eq1+Eq2; } void world::keyPressed( int key ) {} void world::mouseMoved( int x, int y ) { LOD = (unsigned int)ofRangemap(0, ofGetHeight(), 5, 100, y); if( LOD%2 == 1 ) { LOD++; } } void world::mouseDragged( int x, int y, int button ) {} void world::mousePressed( int x, int y, int button ) {} void world::mouseReleased(){} int main() { ofSetupOpenGL( 1024,768, OF_WINDOW ); world APP; ofRunApp( &APP ); }