Vec3 Bezier::SurfNorm(float px, float py) const { Vec3 tempy[4]; Vec3 tempx[4]; Vec3 temp2[4]; //get splines along x axis for (int j = 0; j < 4; ++j) { tempy[j] = Bernstein(px, points[j]); } //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); } Vec3 tx = BernsteinTangent(px, tempx); Vec3 ty = BernsteinTangent(py, tempy); Vec3 n = -tx.cross(ty).Normalize(); return n; }
MATHVECTOR<float,3> BEZIER::SurfCoord(float px, float py) const { MATHVECTOR<float,3> temp[4]; MATHVECTOR<float,3> temp2[4]; int i, j; /*if (px == 0.0 && py == 0.0) return points[3][3]; if (px == 1.0 && py == 1.0) return points[0][0]; if (px == 1.0 && py == 0.0) return points[0][3]; if (px == 0.0 && py == 1.0) return points[3][0];*/ //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 SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv) { Vector num = Vector::From(0, 0, 0), num_u = Vector::From(0, 0, 0), num_v = Vector::From(0, 0, 0); double den = 0, den_u = 0, den_v = 0; int i, j; for(i = 0; i <= degm; i++) { for(j = 0; j <= degn; j++) { double Bi = Bernstein(i, degm, u), Bj = Bernstein(j, degn, v), Bip = BernsteinDerivative(i, degm, u), Bjp = BernsteinDerivative(j, degn, v); num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j])); den += weight[i][j]*Bi*Bj; num_u = num_u.Plus(ctrl[i][j].ScaledBy(Bip*Bj*weight[i][j])); den_u += weight[i][j]*Bip*Bj; num_v = num_v.Plus(ctrl[i][j].ScaledBy(Bi*Bjp*weight[i][j])); den_v += weight[i][j]*Bi*Bjp; } } // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2) *tu = ((num_u.ScaledBy(den)).Minus(num.ScaledBy(den_u))); *tu = tu->ScaledBy(1.0/(den*den)); *tv = ((num_v.ScaledBy(den)).Minus(num.ScaledBy(den_v))); *tv = tv->ScaledBy(1.0/(den*den)); }
Vec3 Bezier::SurfCoord(float px, float py) const { //get splines along x axis Vec3 temp[4]; for (int j = 0; j < 4; ++j) { temp[j] = Bernstein(px, points[j]); } return Bernstein(py, temp); }
VERTEX BEZIER::SurfCoord(float px, float py) { VERTEX temp[4]; VERTEX 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); }
Vector SSurface::PointAt(double u, double v) { Vector num = Vector::From(0, 0, 0); double den = 0; int i, j; for(i = 0; i <= degm; i++) { for(j = 0; j <= degn; j++) { double Bi = Bernstein(i, degm, u), Bj = Bernstein(j, degn, v); num = num.Plus(ctrl[i][j].ScaledBy(Bi*Bj*weight[i][j])); den += weight[i][j]*Bi*Bj; } } num = num.ScaledBy(1.0/den); return num; }
point3 CourbeBezier::calculPuBernstein(const float &progressionCourbe) { point3 pU; for(int j=0; j< tabPoint.size(); j++){ pU = pU + tabPoint[j]*Bernstein(j, getDegree(), progressionCourbe); } return pU; }
Vector SBezier::PointAt(double t) { Vector pt = Vector::From(0, 0, 0); double d = 0; int i; for(i = 0; i <= deg; i++) { double B = Bernstein(i, deg, t); pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i])); d += weight[i]*B; } pt = pt.ScaledBy(1.0/d); return pt; }
void Shape::Bezier (vector<Point> control, vector<Point> *result) { float t; int n = control.size()-1; for (t = 0.0; t < 1.0; t += 0.07) { float xt =0; float yt =0; for(int i=0; i<=n; i++) { xt += control[i].x*Bernstein(i,n,t); yt += control[i].y*Bernstein(i,n,t); } if (result->size()) { if (result->at(result->size()-1).x == xt || result->at(result->size()-1).y == yt) { /* do nothing */ } else { result->push_back(Point(xt,yt,0,0)); } } else { result->push_back(Point(xt,yt,0,0)); } } }
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)).Normalize()); }
/* and the number of divisions */ GLuint genBezier(BEZIER_PATCH patch, int divs) { int u = 0, v; float py, px, pyold; GLuint drawlist = glGenLists(1); /* make the display list */ POINT_3D temp[4]; POINT_3D *last = (POINT_3D*)malloc(sizeof(POINT_3D)*(divs+1)); /* array of points to mark the first line of polys */ if (patch.dlBPatch != 0) /* get rid of any old display lists */ glDeleteLists(patch.dlBPatch, 1); temp[0] = patch.anchors[0][3]; /* the first derived curve (along x axis) */ temp[1] = patch.anchors[1][3]; temp[2] = patch.anchors[2][3]; temp[3] = patch.anchors[3][3]; for (v=0;v<=divs;v++) { /* create the first line of points */ px = ((float)v)/((float)divs); /* percent along y axis */ /* use the 4 points from the derives curve to calculate the points along that curve */ last[v] = Bernstein(px, temp); } glNewList(drawlist, GL_COMPILE); /* Start a new display list */ glBindTexture(GL_TEXTURE_2D, patch.texture); /* Bind the texture */ for (u=1;u<=divs;u++) { py = ((float)u)/((float)divs); /* Percent along Y axis */ pyold = ((float)u-1.0f)/((float)divs); /* Percent along old Y axis */ temp[0] = Bernstein(py, patch.anchors[0]); /* Calculate new bezier points */ temp[1] = Bernstein(py, patch.anchors[1]); temp[2] = Bernstein(py, patch.anchors[2]); temp[3] = Bernstein(py, patch.anchors[3]); glBegin(GL_TRIANGLE_STRIP); /* Begin a new triangle strip */ for (v=0;v<=divs;v++) { px = ((float)v)/((float)divs); /* Percent along the X axis */ glTexCoord2f(pyold, px); /* Apply the old texture coords */ glVertex3d(last[v].x, last[v].y, last[v].z); /* Old Point */ last[v] = Bernstein(px, temp); /* Generate new point */ glTexCoord2f(py, px); /* Apply the new texture coords */ glVertex3d(last[v].x, last[v].y, last[v].z); /* New Point */ } glEnd(); /* END the triangle srip */ } glEndList(); /* END the list */ free(last); /* Free the old vertices array */ return drawlist; /* Return the display list */ }
bool BezierCurveGen::next_point(XnPoint3D &pt) { if (m_i == m_t.size()) { return false; } pt.X = pt.Y = pt.Z = 0.0f; for(size_t j = 0; j < m_controlPoints.size(); j++){ float val = Bernstein(m_controlPoints.size()-1, j, m_t.at(m_i)); pt.X = pt.X + m_controlPoints.at(j).X *val; pt.Y = pt.Y + m_controlPoints.at(j).Y *val; pt.Z = pt.Z + m_controlPoints.at(j).Z *val; } ++m_i; return true; }
Vector SBezier::TangentAt(double t) { Vector pt = Vector::From(0, 0, 0), pt_p = Vector::From(0, 0, 0); double d = 0, d_p = 0; int i; for(i = 0; i <= deg; i++) { double B = Bernstein(i, deg, t), Bp = BernsteinDerivative(i, deg, t); pt = pt.Plus(ctrl[i].ScaledBy(B*weight[i])); d += weight[i]*B; pt_p = pt_p.Plus(ctrl[i].ScaledBy(Bp*weight[i])); d_p += weight[i]*Bp; } // quotient rule; f(t) = n(t)/d(t), so f' = (n'*d - n*d')/(d^2) Vector ret; ret = (pt_p.ScaledBy(d)).Minus(pt.ScaledBy(d_p)); ret = ret.ScaledBy(1.0/(d*d)); return ret; }
void DoubleBezier() { float t = 0; glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINE_STRIP); while (t < 1){ float x = 0, y = 0, z = 0; for (int i = 0; i < OrdrePC; i++){ x += TabPC[i].x* Bernstein(i, OrdrePC - 1, t); y += TabPC[i].y* Bernstein(i, OrdrePC - 1, t); z += TabPC[i].z* Bernstein(i, OrdrePC - 1, t); } glVertex3f(x, y, z); t += 0.01; } glEnd(); // Dessiner ici la courbe de Bézier. // Vous devez avoir implémenté Bernstein précédemment.* t = 0; glColor3f(0.0, 1.0, 0.0); glBegin(GL_LINE_STRIP); while (t < 1){ float x = 0, y = 0, z = 0; for (int i = 0; i < OrdrePC2; i++){ x += TabPC2[i].x* Bernstein(i, OrdrePC2 - 1, t); y += TabPC2[i].y* Bernstein(i, OrdrePC2 - 1, t); z += TabPC2[i].z* Bernstein(i, OrdrePC2 - 1, t); } glVertex3f(x, y, z); t += 0.01; } glEnd(); }
/* * find_bernstein_roots : Given an equation in Bernstein-Bernstein form, find all * of the roots in the open interval (0, 1). Return the number of roots found. */ void find_bernstein_roots(double const *w, /* The control points */ unsigned degree, /* The degree of the polynomial */ std::vector<double> &solutions, /* RETURN candidate t-values */ unsigned depth, /* The depth of the recursion */ double left_t, double right_t) { unsigned n_crossings = 0; /* Number of zero-crossings */ int old_sign = SGN(w[0]); for (unsigned i = 1; i <= degree; i++) { int sign = SGN(w[i]); if (sign) { if (sign != old_sign && old_sign) { n_crossings++; } old_sign = sign; } } switch (n_crossings) { case 0: /* No solutions here */ return; case 1: /* Unique solution */ /* Stop recursion when the tree is deep enough */ /* if deep enough, return 1 solution at midpoint */ if (depth >= MAXDEPTH) { solutions.push_back((left_t + right_t) / 2.0); return; } // I thought secant method would be faster here, but it'aint. -- njh if (control_poly_flat_enough(w, degree, left_t, right_t)) { const double Ax = right_t - left_t; const double Ay = w[degree] - w[0]; solutions.push_back(left_t - Ax*w[0] / Ay); return; } break; } /* Otherwise, solve recursively after subdividing control polygon */ std::vector<double> Left(degree+1); /* New left and right */ std::vector<double> Right(degree+1);/* control polygons */ const double split = 0.5; Bernstein(w, degree, split, &Left[0], &Right[0]); double mid_t = left_t*(1-split) + right_t*split; find_bernstein_roots(&Left[0], degree, solutions, depth+1, left_t, mid_t); /* Solution is exactly on the subdivision point. */ if (Right[0] == 0) solutions.push_back(mid_t); find_bernstein_roots(&Right[0], degree, solutions, depth+1, mid_t, right_t); }
// ============================================================================ // 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 ); }