기본 콘텐츠로 건너뛰기

[MATLAB]3점에 의한 원의 중심 구하기...

원문 출처 : http://mathworld.wolfram.com/Circle.html 중 일부  입니다.

 

The equation of a circle passing through the three points (x_i,y_i) for i=1, 2, 3 (the circumcircle of the triangle determined by the points) is

 |x^2+y^2 x y 1; x_1^2+y_1^2 x_1 y_1 1; x_2^2+y_2^2 x_2 y_2 1; x_3^2+y_3^2 x_3 y_3 1|=0.

 

(25)

The center and radius of this circle can be identified by assigning coefficients of a quadratic curve

 ax^2+cy^2+dx+ey+f=0,

 

(26)

where a=c and b=0 (since there is no xy cross term). Completing the square gives

 a(x+d/(2a))^2+a(y+e/(2a))^2+f-(d^2+e^2)/(4a)=0.

 

(27)

The center can then be identified as

x_0 =

-d/(2a)

 

(28)
y_0 =

-e/(2a)

 

(29)

 

and the radius as

 r=sqrt((d^2+e^2)/(4a^2)-f/a),

 

(30)

where

a =

|x_1 y_1 1; x_2 y_2 1; x_3 y_3 1|

 

(31)
d =

-|x_1^2+y_1^2 y_1 1; x_2^2+y_2^2 y_2 1; x_3^2+y_3^2 y_3 1|

 

(32)
e =

|x_1^2+y_1^2 x_1 1; x_2^2+y_2^2 x_2 1; x_3^2+y_3^2 x_3 1|

 

(33)
f =

-|x_1^2+y_1^2 x_1 y_1; x_2^2+y_2^2 x_2 y_2; x_3^2+y_3^2 x_3 y_3|.

 

(34)

Four or more points which lie on a circle are said to be concyclic. Three points are trivially concyclic since three noncollinear points determine a circle.

 

 

아래는 원문중 원의 공식을 이용해 MATLAB과 OpenCV 행렬 함수를 이용해서 구현된 소스입니다.

 

학교 과제할때 참고한 공식으로 유용하게 사용했습니다.^^

 

관심점 3점을 추출하여 중심점을 계산하기 원할때 사용하시면 좋을것 같습니다. 응용은 알아서 하세요^^

 

예1) 원이 찌그러 졌을때 중심위치 구하기

     바운더리 픽셀의 픽셀중심을 이용하는 것보다 곡율이 일정한 부분을 찾아서 관심점 3점을 이용하면 정확한 원의 중심을 계산할 수 있습니다. Blob의 중심 모멘트가 아닌 기하학 성분의 원의 중심을 구하는 거죠^^

 

예2) 정삼각형 무게중심, 삼각형의 외심(외적원)... (정삼각형이 아닌 일반 삼각형의 무게중심은 될수 없습니다.)

 

예3) 기타..

 

[code cpp]
% //MATLAB
% //1. x1, x2, x3, y1, y2, y3 3점의 좌표를 구한다.(관심점 3점은 원의 궤적이 될수 있는 좌표를 입력해야 합니다.)
x1 = 5; y1 = 0;   % 예) 12시 방향 좌표
x2 = 10; y2 = 5 ; % 예) 3시 방향 좌표
x3 = 5; y3  = 10; % 예) 6시 방향 좌표

% //주어짐 관심점 3점을 행렬에 대입..
a = [x1, y1, 1;    x2, y2, 1;    x3, y3, 1];
d = [x1^2+y1^2, y1, 1;    x2^2+y2^2, y2, 1;    x3^2+y3^2, y3, 1];
e = [x1^2+y1^2, x1, 1;    x2^2+y2^2, x2, 1;    x3^2+y3^2, x3, 1];
f = [x1^2+y1^2, x1, y1;    x2^2+y2^2, x2, y2;    x3^2+y3^2, x3, y3];

% //2. 3점에 대한 원의 방정식을 행렬식에 대입하여, centerx, centery,  radius를 구함..
centerx = -(det(-d)/(2 * det(a)))
centery = -(det(e)/(2 * det(a)))
radius = sqrt( ((det(-d)^2 + det(e)^2) / (4*det(a)^2)) - (det(-f)/det(a)))

[/code]
[code cpp]
//OpenCV
//관심점 3점을 원의 방적식에 대입
float x1, x2, x3, y1, y2, y3;
x1 = 5; y1 = 0;
x2 = 10; y2 = 5;
x3 = 5; y3  = 10;

//a= [x1, y1, 1; x2, y2, 1; x3, y3, 1];
CvMat *matA = cvCreateMat(3, 3, CV_32F); // a행렬
cvmSet(matA, 0, 0, x1);
cvmSet(matA, 0, 1, y1);
cvmSet(matA, 0, 2, 1);
cvmSet(matA, 1, 0, x2);
cvmSet(matA, 1, 1, y2);
cvmSet(matA, 1, 2, 1);
cvmSet(matA, 2, 0, x3);
cvmSet(matA, 2, 1, y3);
cvmSet(matA, 2, 2, 1);

//d = [x1^2+y1^2, y1, 1; x2^2+y2^2, y2, 1; x3^2+y3^2, y3, 1];
CvMat *matD = cvCreateMat(3, 3, CV_32F); // d행렬
cvmSet(matD, 0, 0, x1*x1+y1*y1);
cvmSet(matD, 0, 1, y1);
cvmSet(matD, 0, 2, 1);
cvmSet(matD, 1, 0, x2*x2+y2*y2);
cvmSet(matD, 1, 1, y2);
cvmSet(matD, 1, 2, 1);
cvmSet(matD, 2, 0, x3*x3+y3*y3);
cvmSet(matD, 2, 1, y3);
cvmSet(matD, 2, 2, 1);

//e = [x1^2+y1^2, x1, 1; x2^2+y2^2, x2, 1; x3^2+y3^2, x3, 1];
CvMat *matE = cvCreateMat(3, 3, CV_32F); // e행렬
cvmSet(matE, 0, 0, x1*x1+y1*y1);
cvmSet(matE, 0, 1, x1);
cvmSet(matE, 0, 2, 1);
cvmSet(matE, 1, 0, x2*x2+y2*y2);
cvmSet(matE, 1, 1, x2);
cvmSet(matE, 1, 2, 1);
cvmSet(matE, 2, 0, x3*x3+y3*y3);
cvmSet(matE, 2, 1, x3);
cvmSet(matE, 2, 2, 1);

//f = [x1^2+y1^2, x1, y1; x2^2+y2^2, x2, y2; x3^2+y3^2, x3, y3];
CvMat *matF = cvCreateMat(3, 3, CV_32F); // f행렬
cvmSet(matF, 0, 0, x1*x1+y1*y1);
cvmSet(matF, 0, 1, x1);
cvmSet(matF, 0, 2, y1);
cvmSet(matF, 1, 0, x2*x2+y2*y2);
cvmSet(matF, 1, 1, x2);
cvmSet(matF, 1, 2, y2);
cvmSet(matF, 2, 0, x3*x3+y3*y3);
cvmSet(matF, 2, 1, x3);
cvmSet(matF, 2, 2, y3);

//중심점과 반지름 구하기
float centerx, centery, radius;
centerx = -( -cvDet(matD) / (2 * cvDet(matA)) );
centery = -( cvDet(matE) / (2 * cvDet(matA)) );
radius = sqrt( (((-cvDet(matD) * -cvDet(matD)) + (cvDet(matE)*cvDet(matE))) / (4*(cvDet(matA)*cvDet(matA)))) - (-cvDet(matF)/cvDet(matA)) );

//메모리 해제
cvReleaseMat(&matA);
cvReleaseMat(&matD);
cvReleaseMat(&matE);
cvReleaseMat(&matF);

[/code]



 

 

댓글

이 블로그의 인기 게시물

각도 단위 변환

(1) 각도의 기본 단위 각도를 나타내는 단위입니다. 360분법 으로 표시하는 1도는 사방을 360으로 나눈 크기입니다. 1분은 1도를 60등분한 각이고 1초는 1분을 다시 60등분한 크기입니다. 분(arcminute)과 초(arcsecond)는 시간을 나타내는 단위인 분(minute), 초(second)와 기호가 같은데, 천문학(영어)에서는 둘을 구분하기 위해 각도는 나타내는 단위에는 ' arc- '를 붙여 표기합니다. 각도를 나타내는 다른 방법으로 호도법 이 있습니다. 호도법은 반지름에 대한 호의 길이 단위로 각도를 표시하는 방법으로 사방은 원주율(π)의 2배 크기가 됩니다(360° = 2π rad). 호도법으로 나타낸 각도는 라디안(radian)으로 표시하며, 360분법으로 나타낸 각도를 호도법으로 나타낸 각도로 바꾸어 주려면 360분법으로 나타낸 각도에 π/180을 곱해주면 됩니다. 컴퓨터 프로그램 언어에서 삼각함수를 계산할 때에는 주로 호도법은 쓰고 있습니다. 1도(˚ , degree) : 1˚ = 60′ = 3600″ = π/180 rad 1분(′, arcminute) : 1′ = 60″ = 1/60° 1초(″, arcsecond) : 1″ = 1/60′ = 1/3600° 1라디안(rad, radian) : 1 rad = 180/π° (π = 원주율 = 3.1415926535897932384626433832795) (2) 시간의 기본 단위 시간의 기본단위는 초(second)입니다. 1초는 국제 표준으로 정밀하게 정의되어 있는데, 세슘 원자(세슘-133)가 9,192,631,770번 진동하는 동안의 시간으로 정의되어 있습니다. 본래 1초는 1 평균 태양일의 1/86400로 정의되어 있었지만 지구의 자전 주기는 다소 불규칙하고 느리게 바뀌고 있으므로 균일한 시간을 정의하기에는 부족합니다. 이후 1초는 지구의 공전 주기를 바탕으로 다시 정의 되었다가 지금은 세슘 원자의 특성을 기반으로 새롭게 정의하여

Cramer rule - 크래머 공식

  크래머 공식 (Cramer's rule)은 선형연립방정식의 해를 행렬식 으로 표현하는 선형대수학 의 정리(theorem)이다. 이름은 가브리엘 크래머 (Gabriel Cramer) (1704 - 1752)에게서 유래한다.     방정식이 많은 경우의 실제 해의 계산에 있어서는 그리 유용하지 않지만, 피봇팅(pivoting)이 필요하지 않은 경우 작은 크기의 행렬에서는 가우스 소거법보다 훨씬 효율적이다. 크래머 공식은 연립방정식의 해를 외재적으로 표현하기 때문에 이론의 전개에 유용하다.   연립방정식이 다음과 같은 행렬 간의 곱으로 표현될 때. A x = c   식에서 정사각행렬 (square matrix) A 는 역행렬을 갖고, 벡터 x 는 ( x i ) 를, 벡터 c 는 ( c i ) 를 성분으로 갖는 열벡터이다.   정리는 다음과 같다. 식에서 A i 는 A 의 i 번째 열을 열벡터 c 로 대체한 행렬을 말한다.     예 [ 편집 ] 2x2 행렬에서 공식을 적용해 보면, 주어진 연립방정식이 다음과 같을 때, a x + b y = e c x + d y = f , 이 식은 로 쓸 수 있으며, 공식을 적용하면, 이 된다.         미분기하학에 적용 [ 편집 ]   크래머 공식은 미분기하 문제를 풀 때 매우 유용하다. 두 개의 방정식 , 이라 가정한다. 여기서, u 와 v 는 독립 변수이고, , 라 정의한다.   여기서 의 방정식을 찾는 것은 크래머 공식으로 해결할 수 있다.   첫째 , F,G,x,y 의 미분을 계산한다. dF, dG 에 dx 와 dy 를 대입하면   u 와 v 는 독립적이므로, du 와 dv 의 계수는 0이다. 따라서 계수에 대한 방정식을 다음과 같이 쓸 수 있다.

CTE(Coefficient of Thermal Expansion: 열팽창 계수)

열변형량 계산표.xlsx         측정기기에 대해서 1. 사용 환경은 20℃으로 설정하지 않으면 안되나요?   그런 일은 없겠지만, 물건은 온도가 높아지면 팽창하고, 낮아지면 줄어듭니다. 거기서 공업적 길이를 나타내는 경우에 표준 온도 20℃으로 결정해 그 온도에 있어서의 결과를 나타내게 되어 있습니다. 그것은 ISO 1에 의해, 「길이 측정의 표준 온도는 20℃으로 한다」라고 규정되고 있습니다. 단, 이 규격에는 20℃에 대한 허용치는 나타나지 않습니다만, 별도인 규격으로 예를 들면 JIS Z 8703에서는 광공업에 있어서의 시험(측정이나 측정기의 교정도 포함된다)을 실시하는 장소의 온도에 관한 표준 상태의 허용차이가 규정되고 있습니다.   표준 온도의 허용차이 급별 허용차이 ℃ 온도 0. 5급 ± 0.5 온도 1급 ± 1 온도 2급 ± 2 온도 5급 ± 5 온도 15급 ± 15   즉, 항상 20℃에 정확히 맞추는 것은 매우 곤란해서, 어느 허용차이의 온도 환경이 필요하게 될까는 어느 정도의 정확한 측정이나 시험을 실시하느냐에 달려있다고 봅니다. 고정밀도의 측정을 실시하려면 , 허용차이의 작은 온도 환경이 요구됩니다.   2. 선열팽창 계수를 가르쳐 주세요?   물건은 온도가 높아지면 팽창하고 낮아지면 줄어듭니다. 온도 변화에 의한 물체의 길이의 증감을 수치화한 것이 선열팽창 계수입니다. 아래와 같이에 당사제품의 선열팽창 계수를 몇개인가 올려 보고 싶다고 생각합니다. 제품명 정밀도에 영향을 주는 주요 부분의 재질 선열팽창 계수 게이지 블록(스틸) 강 10.8 X 10 -6 K -1 게이지 블록(세라믹) 지르코니야 9.3 X 10 -6 K -1 저팽창 유리 게이지