Point de_casteljau(Point* control, int i, int r, double t, int start) { if (r == 0) { return control[i+start]; // Retorna o ponto do nivel adequado } else { Point g = de_casteljau(control, i, r-1, t, start); Point h = de_casteljau(control, i+1, r-1, t, start); Point k; k.setCoordXY((1-t)*g.x + t*h.x, (1-t)*g.y + t*h.y); return k; } }
Points* render::bezier(Bezier *curve) { Points *ret = new Points; for (float dt = 0, inc = 1.0/float(curve->res); dt <= 1.0; dt += inc) ret->push_back(de_casteljau(curve->points, dt)); return ret; }
void draw_curve() { Point P, Q; int L = qpoints - 3; if (numpoints <= 4) { float par = 0; while (par <= 1) { Q = de_casteljau(control_points, 0, numpoints-1, par, 0); glBegin(GL_POINTS); glColor3f(0.0f, 0.0f, 237.0f); glVertex2f(Q.x, Q.y); glEnd(); if (par > 0) { glBegin(GL_LINES); glColor3f(0.0f, 0.0f, 237.0f); glVertex2f(Q.x, Q.y); glVertex2f(P.x, P.y); glEnd(); } P.setCoordXY(Q.x, Q.y); par += float(1)/float(factor); } } else { float par = 0; GLfloat u; for (int i = 0; i < L; i++) { u = us[i]; while (u <= us[i+1]) { par = (u - us[i])/(us[i+1] - us[i]); // Parametrização if (i != L-1) { Q = de_casteljau(control_points, 0, 3, par, 3*i); } else { Q = de_casteljau(control_points, 0, numpoints - (1 + 3*i), par, 3*i); } glBegin(GL_POINTS); glColor3f(0.0f, 0.0f, u); glVertex2f(Q.x, Q.y); glEnd(); // Liga um segmento de reta entre dois pontos consecutivos da curva if (u > us[0]) { glBegin(GL_LINES); glColor3f(0.0f, 0.0f, u); glVertex2f(Q.x, Q.y); glVertex2f(P.x, P.y); glEnd(); } P.setCoordXY(Q.x, Q.y); u += (us[L]-us[0])/float(factor); // Divide o intervalo de acordo com o fator escolhido pelo usuario apertando (+/-) } } // Ultimo ponto da curva glBegin(GL_LINES); glColor3f(0.0f, 0.0f, u); glVertex2f(control_points[(3*L)].x, control_points[(3*L)].y); glVertex2f(P.x, P.y); glEnd(); } }