원뿔을 평면으로 잘랐을 때 나타나는 곡선인 conic section은 직교 좌표계에서
이 conic section이 타원을 기술할 때 parameter {
따라서, 적절한 회전 변환을 하면 두 좌표의 곱으로 주어지는
회전 후의 방정식이 타원의 방정식(원점이 이동된)을 기술하기 위해서는
conic section
여기서 회전각
로 주어짐을 확인할 수 있다. Eigenvalue의 제곱근의 역수가 두 축의 반지름을 결정하므로 음수가 되어서는 안된다 (둘 중 하나가 0이면 직선이고, 둘 모두 0이면 한 점에 해당). 이는 대칭행렬의 고유값이 항상 0보다 작지 않다는 사실에서 기인한다. 위에서 구한 회전각
위의 회전변환식을 대입했을 떄 나머지 상수항은 (첫 번째 등호는 계산해서 확인할 수 있음)
로 주어짐을 알 수 있다. 따라서 회전시킨 타원은 표준형 꼴
로 표현된다. 이 표준형 타원의 두 축의 반지름은 각각
// conic_params(a, b, c, d, e, f): ax^2 + bxy + cy^2 + dx + ey + f = 0;
// ellipse_params(radius_x, radius_y, center_x, center_y, tilt_angle w.r.t x-axis);
bool conic_to_ellipse(double conic_params[6], double ellipse_params[5]) {
const double a = conic_params[0];
const double b = conic_params[1];
const double c = conic_params[2];
const double d = conic_params[3];
const double e = conic_params[4];
const double f = conic_params[5];
// get ellipse orientation w.r.t x-axis;
const double theta = 0.5 * atan2(b, a - c);
// get scaled x/y radius;
const double ct = cos(theta);
const double st = sin(theta);
const double ap = a * ct * ct + b * ct * st + c * st * st;
const double cp = a * st * st - b * ct * st + c * ct * ct;
// get center of ellipse;
const double cx = (2 * c * d - b * e) / (b * b - 4 * a * c);
const double cy = (2 * a * e - b * d) / (b * b - 4 * a * c);
// get scale factor
const double val = a * cx * cx + b * cx * cy + c * cy * cy;
const double scale_inv = val - f;
if (scale_inv / ap <= 0 || scale_inv / cp <= 0) {
TRACE("Error! ellipse parameters are imaginary\n");
return 0;
}
ellipse_params[0] = sqrt(scale_inv / ap);
ellipse_params[1] = sqrt(scale_inv / cp);
ellipse_params[2] = cx;
ellipse_params[3] = cy;
ellipse_params[4] = theta;
return 1;
};
'Image Recognition > Fundamental' 카테고리의 다른 글
삼각형의 외접원: 외접원의 중심(center of circumcircle of a triangle) (0) | 2012.10.19 |
---|---|
삼각형의 외접원: 외접원의 반지름(radius of circumcircle of a triangle) (0) | 2012.10.13 |
float 타입 변수의 절대값은? (0) | 2012.02.17 |
x 보다 크거나 같은 가장 작은 2^n ? (0) | 2012.02.13 |
Is Pow of 2 (0) | 2012.02.13 |