타원은 베지어 곡선을 이용해서 근사적으로 표현할 수 있음을 잘 알고 있다(https://kipl.tistory.com/313). 표준형 타원의 경우 1사분면에서 표현만 알면 대칭성에 의해서 나머지 사분면에서는 바로 구할 수 있으므로 거리를 구하는 점이 1사분면에 있는 경우만 알아보면 충분하다. 장축 반지름이
Bezier Curve Approximation of an Ellipse
Bezier 곡선을 이용한 원의 근사처럼 타원을 근사해보도록 하자. 원점을 중심으로 하고 장축 반지름이
kipl.tistory.com
한 점
을 만족하는 근을 찾으면 된다. 풀어야 할 방정식이 5차이므로 직접적으로 근을 찾는 것은 불가능하므로 Newton-Raphson 방법을 사용하도록하자. 앞선 정확한 거리 계산에서와는 달리 초기
//cubic bezier_x: P0(0, 1), P1(k, 1),P2(1, k), P3(1, 0);
double B(double t) { //t in [0:1]
const double k = 4.*(sqrt(2.)-1)/3;
return t*(3*k + t*(3 - 6*k + (-2 + 3*k)*t));
}
// derivative of B(t);
double DB(double t) {
const double k = 4.*(sqrt(2.)-1)/3;
return 3*k + t*(6 - 12*k + (-6 + 9*k)*t);
}
// derivative of DB(t);
double D2B(double t) {
const double k = 4.*(sqrt(2.)-1)/3;
return 6 - 12*k + (-12 + 18*k)*t;
}
// ellipse radii=(a, b);
double dist2EllipseBezier3(double p, double q, double a, double b,
double& xt, double& yt) {
if (a == b) return dist2Circle(p, q, a, xt, yt);
double x = fabs(p), y = fabs(q);
const double eps = 0.001 / max(a, b);
double t = 0.5; // mid
while (1) {
// Newton-Raphson;
double f = a*a*B(t)*DB(t)-b*b*B(1-t)*DB(1-t)-a*x*DB(t)+b*y*DB(1-t);
if (f == 0) break;
double df = a*a*(DB(t)*DB(t)+B(t)*D2B(t))+b*b*(DB(1-t)*DB(1-t)+B(1-t)*D2B(1-t))
-a*x*D2B(t)-b*y*D2B(1-t);
double dt = f / df;
t -= dt;
t = max(0, min(1, t));
if (abs(dt) < eps ) break;
}
xt = a * B(t); yt = b * B(1-t);
xt = p >= 0? xt: -xt;
yt = q >= 0? yt: -yt;
return hypot(p - xt, q - yt);
}

'Computational Geometry' 카테고리의 다른 글
Why Cubic Splines? (9) | 2024.03.16 |
---|---|
Natural Cubic Spline (0) | 2024.03.11 |
Distance from a Point to an Ellipse (0) | 2024.03.06 |
Data Fitting with B-Spline Curves (0) | 2021.04.30 |
Closest Pair of Points (0) | 2021.04.27 |