/* BezierPatchMesh::BezierPatchSample BezierPatchMesh::sample(double u, double v) const { BezierPatchSample ret; ret.uv = Vec2d(u,v); Vec3d x (0,0,0); // Programming TASK 2: implement this method // You need to compute ret.position and ret.normal! // This data will be used within the initialize() function for the // triangle mesh construction. //Tensorprodukt //std::cout << "::::::::::::::::::::::::::::::::::::::::::::::::::" << std::endl; //std::cout << "claculating for u:" << u << " v: " << v << std::endl; for (int i = 0; i < mM ; ++i) { for (int j = 0; j < mN ; ++j) { double Bernsteinpolynom1; double Bernsteinpolynom2; double Binomialkoefizient1 = 1; double Binomialkoefizient2 = 1; if (i <= mM) { Binomialkoefizient1 = factorial(mM) / (factorial(mM - i) * factorial(i)); } else Binomialkoefizient1 = 0; if (j <= mN) { Binomialkoefizient2 = factorial(mN) / (factorial(mN - j) * factorial(j)); } else Binomialkoefizient2 = 0; //if (mM - 1 <= Math::safetyEps() && mM - 1 >= -Math::safetyEps()) Bernsteinpolynom1 = Binomialkoefizient1 * pow(u, i) * 1; Bernsteinpolynom1 = Binomialkoefizient1 * pow(u, i) * pow((1 - u), (mM - i)); //if (mN - 1 <= Math::safetyEps() && mN - 1 >= -Math::safetyEps()) Bernsteinpolynom2 = Binomialkoefizient2 * pow(v, j) * 1; Bernsteinpolynom2 = Binomialkoefizient2 * pow(v, j) * pow((1 - v), (mN - j)); x += (controlPoint(i, j) * Bernsteinpolynom1 * Bernsteinpolynom2); //std::cout << "i: " << i << "j: " << j << ", Bp1: " << Bernsteinpolynom1 << ", Bp2: " << Bernsteinpolynom2 << ", cP: " << controlPoint(i, j) << std::endl; } } ret.position = x; ret.normal = Vec3d(); return ret; } */ Vec3d BezierPatchMesh::deCasteljau(Vec3d b, double t, size_t r, size_t i) const { if (r == 0) { return controlPoint(r, i); } else { return ((1 - t) * (deCasteljau(b, t, (r - 1), i) + (t * deCasteljau(b, t, (r - 1), (i + 1))))); } }
std::vector<Ponto> bezierCurve::generatePoints(double inc) { std::vector<Ponto> result; double t = 0.0; int dg = this->controlPoints.size(); while(t <= 1.0) { passo++; result.push_back(deCasteljau(dg-1, 0, t)); t += inc; } if(t>1.0) { passo++; result.push_back(deCasteljau(dg-1, 0, 1.0)); } return result; }
void keyboard(unsigned char key, int x, int y) { switch (key) { case 8: // BACKSPACE if (Points.size() > 0) { std::cout << "deleted point at (" << (Points.end()-1)->X << ", " << (Points.end()-1)->Y << ")" << std::endl; Points.pop_back(); } break; case 32: // SPACE isCasteljau = !isCasteljau; if(isCasteljau) { deCasteljau(); } else { deBoor(); } break; case 27: // ESC exit(0); break; } glutPostRedisplay(); }
/* * use the de Casteljau algorithm to subdivide the Bezier curve divisions times, * then add the lines connecting the control points to the module. */ void module_bezierCurve(Module *m, BezierCurve *b, int divisions){ Line tempLine; Point deCast[7]; BezierCurve tempbez; if(!m || !b){ printf("Null passed to module_bezierCurve\n"); return; } // base case, add six lines to module if(divisions == 0){ line_set(&tempLine, b->c[0], b->c[1]); module_line(m, &tempLine); line_set(&tempLine, b->c[1], b->c[2]); module_line(m, &tempLine); line_set(&tempLine, b->c[2], b->c[3]); module_line(m, &tempLine); return; } // compute all avg points for 3 orders, down to just one point 3rd order deCasteljau(&(deCast[0]), &(b->c[0])); // left half bezierCurve_set(&tempbez, &(deCast[0])); module_bezierCurve(m, &tempbez, divisions-1); // right half bezierCurve_set(&tempbez, &(deCast[3])); module_bezierCurve(m, &tempbez, divisions-1); }
void subdivision (Point2d* bez, int deg) { //subdivide a bezier curve into two curves Point2d p; p.x = 0; p.y = 0; Point2d** pki = (Point2d **) malloc ((deg+1)*(deg+1)*sizeof(Point2d)); Point2d* bez1 = (Point2d *) malloc ((deg+1)*sizeof(Point2d)); Point2d* bez2 = (Point2d *) malloc ((deg+1)*sizeof(Point2d)); double t; t = 0.5; double error = getError(bez, deg); // if the maximal distance is greater than a threshold, the curve is to be subdivided into two parts if ( error>tessEps){ pki = deCasteljau(deg, t, bez); // de Casteljau algorithm for (int i=0; i<=deg; i++){ bez1[i] = pki[i][0]; // the left sub-curve bez2[i] = pki[deg-i][i]; // the right sub-curve } subdivision(bez1, deg); subdivision(bez2, deg); } // else, draw a line from the first control point and the last one else{ glVertex2f(bez[0].x, bez[0].y); glVertex2f(bez[deg].x, bez[deg].y); return; } }
BezierPatchMesh::BezierPatchSample BezierPatchMesh::sample(double u, double v) const { BezierPatchSample ret; ret.uv = Vec2d(u, v); //std::vector<Vec3d> P = mControlPoints; size_t m = mM; size_t n = mN; //controlPoints(i,j) std::vector<Vec3d> q; Vec3d p; for (int i = 0; i < m; ++i) { for (size_t r = 1; r <= n; ++r) { for (size_t j = 0; j <= (n - r); ++j) { // 3 - 1 = 2, 3 - 2 = 1, 3 - 3 = 0 q[i] = deCasteljau(controlPoint(j, 0), v, i + 1, j); } } for (int j = 0; j < n; ++j) { } deCasteljauQ(q[i], u, , , q) } for (size_t r = 1; r <= n; ++r) { for (size_t i = 0; i <= (n + r); ++i) { p = deCasteljauQ(temp[i], u, r, i, temp); } } // Programming TASK 2: implement this method // You need to compute ret.position and ret.normal! // This data will be used within the initialize() function for the // triangle mesh construction. ret.position = p; ret.normal = Vec3d(); return ret; }
void deCasteljau() { const int steps = 100; const double inc = 1.0 / steps; Lines.clear(); std::cout << "DeCasteljau" << std::endl; for(double t = 0.0; t <= 1.0; t += inc) { Lines.push_back(deCasteljau(t)); } }
// De Casteljau algorithm contributed by Jed Soane void FTVectoriser::evaluateCurve( const int n) { // setting the b(0) equal to the control points for( int i = 0; i <= n; i++) { bValues[0][i][0] = ctrlPtArray[i][0]; bValues[0][i][1] = ctrlPtArray[i][1]; } float t; //parameter for curve point calc. [0.0, 1.0] for( int m = 0; m <= ( 1 / kBSTEPSIZE); m++) { t = m * kBSTEPSIZE; deCasteljau( t, n); //calls to evaluate point on curve att. } }
QList<QPointF> BezierCalc::computeCn1(const QList<QPointF>& controllPoints, const QPointF& newPoint) { const double t = 2; QList<QPointF> consecutivePoints; deCasteljau(consecutivePoints, controllPoints, controllPoints.size(), t); QList<QPointF> resultPoints; for (int i = consecutivePoints.size() - 1; i > controllPoints.size(); --i) { resultPoints.append(consecutivePoints[i]); } resultPoints.append(newPoint); return resultPoints; }
void BezierCalc::computeSelfIntersectionFreeSegments( const QList<QPointF>& bezierPolygon, QList<QList<QPointF>>& resultSegments) { const double t = 0.5; const double angle = getTotalAngle(bezierPolygon); if (angle < 180) { resultSegments.append(bezierPolygon); } else { QList<QPointF> newBezierPolygon; deCasteljau(newBezierPolygon, bezierPolygon, bezierPolygon.size(), t); QList<QPointF> left, right; splitIntoHalf(newBezierPolygon, left, right); computeSelfIntersectionFreeSegments(left, resultSegments); computeSelfIntersectionFreeSegments(right, resultSegments); } }
void BezierCalc::deCasteljau(QList<QPointF>& resultCurve, const QList<QPointF>& controllPoints, const int degree, const float t) { QList<QPointF> tmpPoints; if (degree > 0) { // add first point resultCurve.append(controllPoints.first()); for (int i = 0; i < degree - 1; ++i) { // lerp tmpPoints.append((1.0 - t) * controllPoints[i] + t * controllPoints[i + 1]); } deCasteljau(resultCurve, tmpPoints, degree - 1, t); // add last point resultCurve.append(controllPoints.last()); } }
void BezierCalc::calcBezierCurvePolar(const QList<QPointF>& controllPoints, const int k, const double epsilon, QList<QPointF>& result) { const double t = 0.5; const double maxDist = getMaxForwardDistance(controllPoints); if (k == 0 || maxDist < epsilon) { result.append(controllPoints); } else { QList<QPointF> curvePoints; deCasteljau(curvePoints, controllPoints, controllPoints.size(), t); QList<QPointF> leftHalf; QList<QPointF> rightHalf; splitIntoHalf(curvePoints, leftHalf, rightHalf); calcBezierCurvePolar(leftHalf, k - 1, epsilon, result); calcBezierCurvePolar(rightHalf, k - 1, epsilon, result); } }
Vector3D eval(double u, double v, Vector3D (*P)[4][4]) { Vector3D Q[4]; for (int j = 0; j <= 3; j++) Q[j] = deCasteljau(u, &(*P)[j]); return deCasteljau(v, &Q); }
void deCasteljau(ControlPoint& a, ControlPoint& b, double t, ControlPoint& mid) { deCasteljau(a.pos, a.delta_after, b.delta_before, b.pos, t, mid); }
/* * use the de Casteljau algorithm to subdivide the Bezier surface divisions times, * then draw either the lines connecting the control points, if solid is 0, * or draw triangles connecting the surface. */ void module_bezierSurface(Module *m, BezierSurface *b, int divisions, int solid){ int i, j, k, l; Line tempLine; Point grid[7][7]; Point controls[7]; Point deCast[7]; Point surfacePoints[16]; BezierSurface tempBezSurf; Polygon *temptri = polygon_create(); if(!m || !b){ printf("Null passed to module_bezierSurface\n"); return; } // base case if(divisions == 0){ // lines if(solid == 0){ for(i=0;i<4;i++){ for(j=0;j<3;j++){ line_set(&tempLine, b->c[i][j], b->c[i][j+1]); module_line(m, &tempLine); line_set(&tempLine, b->c[j][i], b->c[j+1][i]); module_line(m, &tempLine); } } } // triangles else { controls[0] = b->c[0][0]; controls[1] = b->c[0][3]; controls[2] = b->c[3][3]; controls[3] = b->c[3][0]; controls[4] = b->c[0][0]; polygon_set(temptri, 3, &(controls[0])); module_polygon(m, temptri); polygon_set(temptri, 3, &(controls[2])); module_polygon(m, temptri); } } // divide and recurse else { // compute all avg points for 3 orders, down to just one point 3rd order // do for each of the four bezier curves for(i=0;i<4;i++){ deCasteljau(&(deCast[0]), &(b->c[i][0])); for(j=0;j<7;j++){ grid[2*i][j] = deCast[j]; } } // now traverse the other direction, populating grid for(i=0;i<7;i++){ for(j=0;j<4;j++){ controls[j] = grid[2*j][i]; } deCasteljau(&(deCast[0]), &(controls[0])); for(j=0;j<7;j++){ grid[j][i] = deCast[j]; } } // now make the four new bezier surfaces by subdividing across for(i=0;i<2;i++){ for(j=0;j<2;j++){ for(k=0;k<4;k++){ for(l=0;l<4;l++){ surfacePoints[4*k+l] = grid[k+3*i][l+3*j]; } } bezierSurface_set(&tempBezSurf, &(surfacePoints[0])); // recursive call module_bezierSurface(m, &tempBezSurf, divisions-1, solid); } } } // clean up polygon_free(temptri); }
// ============================================================================ // Get point on the curve at time t // ============================================================================ CPoint2D CBezierWnd::GetBezierPoint( const PointList &points, float t ) { return m_bBernstein ? Bernstein( points, t ) : deCasteljau( points, t ); }