n 차 Bezier 곡선은 두 개의 (n - 1) 차 Bezier 곡선의 선형보간으로 표현할 수 있다. Bezier 곡선은 Bernstein 다항식을 이용해서도 표현할 수도 있지만, 높은 찻수의 곡선일 때는 De Casteljau's Algorithm을 이용하는 것이 수치적으로 보다 안정적인 결과를 준다.
// De Casteljau's algorithm; recursive version; slow for larger deg;
double Bezier(int deg, double Q[], double t) {
if (deg == 0) return Q[0];
else if (deg == 1) return (1-t)*Q[0] + t*Q[1];
else if (deg == 2) return (1-t)*((1-t)*Q[0] + t*Q[1]) + t*((1-t)*Q[1] + t*Q[2]);
else return (1 - t) * Bezier(deg-1, &Q[0], t) + t * Bezier(deg-1, &Q[1], t);
}
// De Casteljau's algorithm(degree=n-1);
// non-recursive. Bezier() modifies Q's;
double Bezier(int deg, double Q[], double t) {
if (deg==0) return Q[0];
else if (deg==1) return (1-t)*Q[0] + t*Q[1];
else if (deg==2) return (1-t)*((1-t)*Q[0] + t*Q[1]) + t*((1-t)*Q[1] + t*Q[2]);
for (int k = 0; k < deg; k++)
for (int j = 0; j < (deg - k); j++)
Q[j] = (1 - t) * Q[j] + t * Q[j + 1];
return Q[0];
}
std::vector<CfPt> BezierCurve(const std::vector<CfPt> &cntls, const int segments) {
std::vector<double> xp(cntls.size()), yp(cntls.size());
std::vector<CfPt> curves(segments + 1);
for (int i = 0; i <= segments; ++i) {
double t = double(i) / segments;
// clone control points; non-rec version modifies inputs;
for (int k = cntls.size(); k-->0;) {
xp[k] = cntls[k].x; yp[k] = cntls[k].y;
}
curves[i] = CfPt(Bezier(xp.size()-1, &xp[0], t), Bezier(yp.size()-1, &yp[0], t));
}
return curves;
};
728x90
'Computational Geometry' 카테고리의 다른 글
Flatness of Cubic Bezier Curve (0) | 2021.04.23 |
---|---|
Convexity of Bezier Curve (0) | 2021.04.22 |
Arc Length of Bezier Curves (0) | 2021.04.21 |
Bezier Curve Approximation of an Ellipse (0) | 2021.04.11 |
Bezier Curve Approximation of a Circle (0) | 2021.04.10 |