/** bezier curve algorithm **/ static void bezier_point(VALUE points, float u, float * x, float * y, int n, int format, int draw_offset_x, int draw_offset_y) { int xy_index; double sumx = 0, sumy = 0; for(int k = 0; k < n; k++) { switch(format) { case POINT_FORMAT: sumx += NUM2DBL(point_x(get_from_array(points, k))) * bernstein(n - 1, k, u); sumy += NUM2DBL(point_y(get_from_array(points, k))) * bernstein(n - 1, k, u); break; case SIMPLE_FORMAT: xy_index = k * 2; sumx += NUM2DBL(get_from_array(points, xy_index)) * bernstein(n - 1, k, u); sumy += NUM2DBL(get_from_array(points, xy_index + 1)) * bernstein(n - 1, k, u); break; default: rb_raise(rb_eArgError, "pixel format must be either POINT_FORMAT or SIMPLE_FORMAT"); } } *x = sumx + draw_offset_x; *y = sumy + draw_offset_y; }
static double bernstein(int i, int n, double t) { //i is index of control point, n is one less than number of control points if(n == 1) { if(i == 0) return 1-t; if(i == 1) return t; return 0; } if(i < 0 || i > n) return 0; return (1 - t) * bernstein(i, n-1, t) + t * bernstein(i-1, n-1, t); }
MathVector<float, 3> Bezier::surfCoord(float px, float py) const { MathVector<float, 3> temp[4]; MathVector<float, 3> temp2[4]; int i, j; // Get splines along x axis for (j = 0; j < 4; j++) { for (i = 0; i < 4; ++i) { temp2[i] = points[j][i]; } temp[j] = bernstein(px, temp2); } return bernstein(py, temp); }
void evaluate_bezier_curve(float *x, float *y, control_point p[], int num_points, float u) { *x = 0.0; *y = 0.0; for (int i = 0; i < num_points; i++) { float bern = bernstein(num_points - 1, i, u); *x += bern * p[i].x; *y += bern * p[i].y; } }
float2 getPoint(float t) //calculates a point from the control points { float2 r(0.0, 0.0); float weight; // for every control point for (float i = 0; i < controlPoints.size(); i++) { // compute weight using the Bernstein formula weight = bernstein(i, controlPoints.size()-1, t); r += controlPoints.at(i)*weight; } // add control point to r, weighted return r; }
QPointF BPiece::operator ()(double t) const { QPointF r; switch (_type) { case Middle: r += ( cube(1 - t) )/6.0 * _a->point(); r += ( 3*cube(t) - 6*sqr(t) + 4)/6.0 * _b->point(); r += (-3*cube(t) + 3*sqr(t) + 3*t + 1)/6.0 * _c->point(); r += ( cube(t) )/6.0 * _d->point(); break; case End: r += ( cube(1 - t) )/6.0 * _a->point(); r += ( 2*cube(t) - 6*sqr(t) + 4)/6.0 * _b->point(); r += (-7*cube(t) + 3*sqr(t) + 3*t + 1)/6.0 * _c->point(); r += ( cube(t) )/1.0 * _d->point(); break; case Start: r += ( cube(1 - t) )/1.0 * _a->point(); r += (12*t-18*sqr(t)+7*cube(t))/6.0 * _b->point(); r += (6*t-2*cube(t))/6.0 * _c->point(); r += ( cube(t) )/6.0 * _d->point(); break; case Bezier: { double b0, b1, b2, b3; if (_d) { bernstein(t, b0, b1, b2, b3); } else { bernstein(t, b0, b1, b2); } r += b0 * _a->point(); r += b1 * _b->point(); r += b2 * _c->point(); if (_d) r+= b3 * _d->point(); } } return r; }
ofVec3f ofxFfd::deform(const ofVec3f & p){ ofVec3f STUp = convertToSTU(p); /********* CALCUALTE THE TRIVARIATE BERNSTEIN FUNCTION **********/ ofVec3f ffd3, ffd2, ffd1; double bpS = 0, bpT = 0, bpU = 0; ffd3.x = ffd3.y = ffd3.z = 0; ffd2.x = ffd2.y = ffd2.z = 0; ffd1.x = ffd1.y = ffd1.z = 0; for(int i = 0; i <= l; i++) { ffd2.x = 0; ffd2.y = 0; ffd2.z = 0; for(int j = 0; j <= m; j++) { ffd3.x = 0; ffd3.y = 0; ffd3.z = 0; for(int k = 0; k <= n; k++) { bpU = bernstein(k, n, STUp.z); ffd3.x = ffd3.x + (bpU * PCI[i][j][k].x); ffd3.y = ffd3.y + (bpU * PCI[i][j][k].y); ffd3.z = ffd3.z + (bpU * PCI[i][j][k].z); } bpT = bernstein(j, m, STUp.y); ffd2.x = ffd2.x + (bpT * ffd3.x); ffd2.y = ffd2.y + (bpT * ffd3.y); ffd2.z = ffd2.z + (bpT * ffd3.z); } bpS = bernstein(i, l, STUp.x); ffd1.x = ffd1.x + (bpS * ffd2.x); ffd1.y = ffd1.y + (bpS * ffd2.y); ffd1.z = ffd1.z + (bpS * ffd2.z); } return ffd1; }
void util::CubicBezierCurve::_rasterizeDirect(unsigned k) { m_rasterizedPoints.resize(k); float step = 1.0 / (float)k; float t = 0.0f; for (unsigned i = 0; i < k; i++, t += step) { Point2f point(0.0f); for (unsigned j = 0; j < m_degree; j++) { float bern = bernstein(m_degree-1, j, t); point += bern * m_controlPoints[j]; } m_rasterizedPoints[i] = point; } }
MathVector<float, 3> Bezier::surfNorm(float px, float py) const { MathVector<float, 3> temp[4]; MathVector<float, 3> temp2[4]; MathVector<float, 3> tempx[4]; // Get splines along x axis for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; ++i) { temp2[i] = points[j][i]; } temp[j] = bernstein(px, temp2); } // Get splines along y axis for (int j = 0; j < 4; j++) { for (int i = 0; i < 4; ++i) { temp2[i] = points[i][j]; } tempx[j] = bernstein(py, temp2); } return -(bernsteinTangent(px, tempx).cross(bernsteinTangent(py, temp)).normalized()); }
Vector3 Spline3::compute(float distance) { float b[4]; bernstein(distance, b); return (p[0] * b[0] + p[1] * b[1] + p[2] * b[2] + p[3] * b[3]); }
void Curve::drawSurface() { /* * for(int row = 0; row <= vDegree; row++) { std::vector<std::string> strs; boost::split(strs, line, boost::is_space()); for(int i = 0; i < 3*(uDegree+1); i++) { string d = strs.at(i); sscanf(d.c_str(),"%f",&(coordinates[i][index])); } } * */ /* First we get the triangle vertices, then we draw the mesh */ float *** realPoints = new float**[vDegree+1]; for(int v = vDegree; v >= 0; v--) { realPoints[v] = new float*[uDegree+1]; for(int u = 0; u <= uDegree; u++) { float * coord = new float[3]; coord[0] = points[v][3*u]; coord[1] = points[v][3*u+1]; coord[2] = points[v][3*u+2]; realPoints[v][u] = coord; } } int numSamples = pow(3,precision-1) * vDegree; float *** matrix = new float**[numSamples + 1]; for(int i = 0; i <= numSamples; i++) { matrix[i] = new float*[numSamples + 1]; } for(int vIndex = 0; vIndex <= numSamples; vIndex++) { for(int uIndex = 0; uIndex <= numSamples; uIndex++) { float * coordinates = new float[3]; coordinates[0] = 0; coordinates[1] = 0; coordinates[2] = 0; for(int i = 0; i < vDegree+1; i++) { for(int j = 0; j < uDegree+1; j++) { float v = (float) vIndex / (float) numSamples; float u = (float) uIndex / (float) numSamples; float * b_ij = realPoints[i][j]; float B_i = bernstein(i, vDegree, v); float B_j = bernstein(j, uDegree, u); float c = B_i + B_j; coordinates[0] += c * b_ij[0]; coordinates[1] += c * b_ij[1]; coordinates[2] += c * b_ij[2]; } } matrix[vIndex][uIndex] = coordinates; } } glPushMatrix(); glMultMatrixf(transform); /* Now we draw the mesh from the sampled points */ bool br = false; float black[] = {0.0, 0.0, 0.0}; float red[] = {1.0, 0.0, 0.0}; for(int v = 0; v < numSamples; v++) { glBegin(GL_TRIANGLE_STRIP); for(int u = 0; u <= numSamples; u++) { float * p1 = matrix[v][u]; float * p2 = matrix[v+1][u]; if(br) { glColor3fv(black); br = false; } else { glColor3fv(red); br = true; } glVertex3fv(p1); glVertex3fv(p2); } glEnd(); } glPopMatrix(); for(int i = 0; i <= numSamples; i++) { for(int j = 0; j <= numSamples; j++) { delete[] matrix[i][j]; } delete[] matrix[i]; } delete[] matrix; }