void Draw() { //Function to Draw the BEzier Curve glClear(GL_COLOR_BUFFER_BIT); glColor3f(0.0, 1.0, 0.0); glPointSize(5.0); glBegin(GL_POINTS); //Drawing the Four control points glVertex2fv(bez_pnt[0]); glColor3f(0.0, 1.0, 0.0); glVertex2fv(bez_pnt[1]); glColor3f(0.0, 1.0, 0.0); glVertex2fv(bez_pnt[2]); glColor3f(0.0, 1.0, 0.0); glVertex2fv(bez_pnt[3]); glEnd(); while(bez_t <= 1) //Parametric curve from t=0 to t=1 { i=3; while(i>0) { for(j=0;j<i;j++) { bez_pnt[j][0]=decasteljau(bez_t,bez_pnt[j][0],bez_pnt[j+1][0]); bez_pnt[j][1]=decasteljau(bez_t,bez_pnt[j][1],bez_pnt[j+1][1]); } i=i-1; } glColor3f(0.0, 0.0, 1.0); glPointSize(1.0); glBegin(GL_POINTS); //Draw the points on curve glVertex2fv(bez_pnt[0]); glEnd(); bez_t=bez_t+0.00001; //Increment t by 0.00001 } glFlush(); }
static void decasteljau(double tol, std::vector<sortedPoint> &discrete, int pos, const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2, double t0, double t2) { if(sqDistPointSegment(p1, p0, p2) < tol * tol) return; SPoint3 p01((p0 + p1) * 0.5); SPoint3 p12((p1 + p2) * 0.5); SPoint3 p012((p01 + p12) * 0.5); double t012 = 0.5 * (t0 + t2); int newpos = sortedPointInsert(p012, t012, discrete, pos); decasteljau(tol, discrete, pos, p0, p01, p012, t0, t012); decasteljau(tol, discrete, newpos, p012, p12, p2, t012, t2); }
void decasteljau(double tol, const SPoint3 &p0, const SPoint3 &p1, const SPoint3 &p2, const SPoint3 &p3, std::vector<SPoint3> &pts, std::vector<double> &ts) { std::vector<sortedPoint> discrete; sortedPoint pnt1 = {p0, 0., 1}; discrete.push_back(pnt1); sortedPoint pnt2 = {p3, 1., -1}; discrete.push_back(pnt2); decasteljau(tol, discrete, 0, p0, p1, p2, p3, 0., 1); sortedPointToVector(discrete, pts, ts); }
void decasteljau(double tol, const std::vector<SPoint3> &controlPoints, std::vector<SPoint3> &pts, std::vector<double> &ts) { std::vector<sortedPoint> discrete; sortedPoint pnt1 = {controlPoints[0], 0., 1}; discrete.push_back(pnt1); sortedPoint pnt2 = {controlPoints.back(), 1., -1}; discrete.push_back(pnt2); decasteljau(tol, discrete, 0, controlPoints, 0., 1); sortedPointToVector(discrete, pts, ts); }
static void decasteljau(double tol, std::vector<sortedPoint> &discrete, int pos, const std::vector<SPoint3> &pts, double t0, double te) { int order = (int)pts.size() - 1; double dmax2 = 0; for (int i = 1; i < order ; ++i) dmax2 = std::max(dmax2, sqDistPointSegment(pts[i], pts[0], pts[order])); if(dmax2 < tol * tol) return; std::vector<SPoint3> sub0(pts.size()); std::vector<SPoint3> sub1(pts); for (int l = 0; l < order + 1; ++l) { sub0[l] = sub1[0]; for (int i = 0; i < order - l; ++i) sub1[i] = (sub1[i] + sub1[i + 1]) * 0.5; } double tmid = 0.5 * (t0 + te); int newpos = sortedPointInsert(sub1[0], tmid, discrete, pos); decasteljau(tol, discrete, pos, sub0, t0, tmid); decasteljau(tol, discrete, newpos, sub1, tmid, te); }
int draw_curve(const Vec coords[], size_t count) { int segc = 0; int ret; Vec* curve; if(coords == NULL) { return -1; // nurupo~ } for(int i = 0, j = 1; j < count; i++, j++) { segc += ceil(vecdist(coords[i], coords[j]) * 16); } curve = malloc(sizeof (Vec) * segc); if(curve == NULL) { return -1; // malloc error } for(int i = 0; i < segc; i++) { curve[i] = decasteljau(coords, count, (double)i / segc); } ret = draw_polyline(curve, segc); free(curve); return ret; }
void gmshEdge::discretize(double tol, std::vector<SPoint3> &pts, std::vector<double> &ts) { switch(c->Typ) { case MSH_SEGM_LINE : { int NPt = List_Nbr(c->Control_Points); pts.resize(NPt); ts.resize(NPt); for (int i = 0; i < NPt; ++i) { pts[i]= curveGetPoint(c, i); ts[i] = i / (double) (NPt - 1); } return; } case MSH_SEGM_BEZIER : { int NbCurves = (List_Nbr(c->Control_Points) - 1) / 3; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); SPoint3 pt[4]; for(int i = 0; i < 4; i++) { pt[i] = curveGetPoint(c, iCurve * 3 + i); } std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, pt[0], pt[1], pt[2], pt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_BSPLN: { bool periodic = (c->end == c->beg); int NbControlPoints = List_Nbr(c->Control_Points); int NbCurves = NbControlPoints + (periodic ? -1 : 1); SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); for(int i = 0; i < 4; i++) { int k; if (periodic) { k = (iCurve - 1 + i) % (NbControlPoints - 1); if (k < 0) k += NbControlPoints - 1; } else { k = std::max(0, std::min(iCurve - 2 + i, NbControlPoints -1)); } pt[i] = curveGetPoint(c, k); } SPoint3 bpt[4] = { (pt[0] + pt[1] * 4 + pt[2]) * (1./6.), (pt[1] * 2 + pt[2]) * (1./3.), (pt[1] + pt[2] * 2) * (1./3.), (pt[1] + pt[2] * 4 + pt[3]) * (1./6.) }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } case MSH_SEGM_SPLN: { int NbCurves = List_Nbr(c->Control_Points) - 1; SPoint3 pt[4]; for (int iCurve = 0; iCurve < NbCurves; ++iCurve) { double t1 = (iCurve) / (double)(NbCurves); double t2 = (iCurve+1) / (double)(NbCurves); pt[1] = curveGetPoint(c, iCurve); pt[2] = curveGetPoint(c, iCurve + 1); if(iCurve == 0) { if(c->beg == c->end) pt[0] = curveGetPoint(c, NbCurves - 1); else pt[0] = SPoint3(pt[1] * 2 - pt[2]); } else pt[0] = curveGetPoint(c, iCurve - 1); if(iCurve == NbCurves - 1) { if(c->beg == c->end) pt[3] = curveGetPoint(c, 1); else pt[3] = SPoint3(2 * pt[2] - pt[1]); } else pt[3] = curveGetPoint(c, iCurve + 2); SPoint3 bpt[4] = { pt[1], (pt[1] * 6 + pt[2] - pt[0]) * (1./6.), (pt[2] * 6 - pt[3] + pt[1]) * (1./6.), pt[2] }; std::vector<double> lts; std::vector<SPoint3> lpts; decasteljau(tol, bpt[0], bpt[1], bpt[2], bpt[3], lpts, lts); for (size_t i = (iCurve == 0 ? 0 : 1); i < lpts.size(); ++i) { pts.push_back(lpts[i]); ts.push_back(t1 + lts[i] * (t2 - t1)); } } break; } default : GEdge::discretize(tol, pts, ts); } }