임의의 축 <A>는 X , Y ,Z 에 대한 요소를 가지고 있습니다.
<A> 의 X,Y,Z 요소 중 나머지 두 요소를 제거하여 하나만 남긴다면 위에서 알아본 회전 변환에 대한 행렬식을 그대로 쓸 수가 있습니다.
그럼 문제는 어떻게 나머지 두 요소를 제거하느냐의 문제가 됩니다.
우리는 Z 요소만을 남기고 나머지 두 개의 요소를 제거하도록 하겠습니다.
<A> 에서 X , Y 요소를 제거하려면 <A> 을 회전을 시켜 Z 축에 일치시키면 X ,Y 두 요소가 사라질 것입니다.
일단 <A> 을 Y-Z 평면상에 내린 후에 Z축과의 각을 \alpha 라고 하고,
X축을 \alpha 만큼 회전을 시키면 축 <A>는 X-Z평면상에 놓이게 되고, 다시 여기에서 Z축과의 각을 \beta 라고 하자. 그리고 Y축을 \beta만큼 회전을 시키면 축 <A>는 Z축과 동일하게 됩니다.
이제 Z축을 원하는 각도만큼 회전을 시킨 후에 앞의 순서를 거꾸로 하면 원래의 위치에 원하는 각도만큼 회전되어 놓이게 됩니다.
여기에서 우리가 구해야 할 변수는 \alpha,\beta 입니다.
먼저 \alpha을 구하기 위해 <A>축을 Y-Z평면 상에 내린 후에, d=\sqrt{(c^2_y + c^2_z)}\\ cos(\alpha)=\frac{c_z}{d},sin(\alpha)=\frac{c_y}{d} 을 사용해서 \alpha을 구할 수가 있습니다.
여기서 C_x,C_y,C_z는 축 <A>의 방향 코사인입니다.
beta는,
cos(\beta)=d,sin(\beta)=c_x 을 사용해서 구할 수가 있습니다.
이렇게 해서 \alpha,\beta을 구해서 축 <A>을 X축에 대하여 \alpha만큼, Y축에 대하여 beta만큼 회전을 시키면 Z축과 일치하게 됩니다.
<A>을 Z축에 일치시킨 후에 Z축을 원하는 각도만큼(여기서는 \theta라고 하자.)회전을 하면 됩니다.
<A> 의 X,Y,Z 요소 중 나머지 두 요소를 제거하여 하나만 남긴다면 위에서 알아본 회전 변환에 대한 행렬식을 그대로 쓸 수가 있습니다.
그럼 문제는 어떻게 나머지 두 요소를 제거하느냐의 문제가 됩니다.
우리는 Z 요소만을 남기고 나머지 두 개의 요소를 제거하도록 하겠습니다.
<A> 에서 X , Y 요소를 제거하려면 <A> 을 회전을 시켜 Z 축에 일치시키면 X ,Y 두 요소가 사라질 것입니다.
일단 <A> 을 Y-Z 평면상에 내린 후에 Z축과의 각을 \alpha 라고 하고,
X축을 \alpha 만큼 회전을 시키면 축 <A>는 X-Z평면상에 놓이게 되고, 다시 여기에서 Z축과의 각을 \beta 라고 하자. 그리고 Y축을 \beta만큼 회전을 시키면 축 <A>는 Z축과 동일하게 됩니다.
이제 Z축을 원하는 각도만큼 회전을 시킨 후에 앞의 순서를 거꾸로 하면 원래의 위치에 원하는 각도만큼 회전되어 놓이게 됩니다.
여기에서 우리가 구해야 할 변수는 \alpha,\beta 입니다.
먼저 \alpha을 구하기 위해 <A>축을 Y-Z평면 상에 내린 후에, d=\sqrt{(c^2_y + c^2_z)}\\ cos(\alpha)=\frac{c_z}{d},sin(\alpha)=\frac{c_y}{d} 을 사용해서 \alpha을 구할 수가 있습니다.
여기서 C_x,C_y,C_z는 축 <A>의 방향 코사인입니다.
beta는,
cos(\beta)=d,sin(\beta)=c_x 을 사용해서 구할 수가 있습니다.
이렇게 해서 \alpha,\beta을 구해서 축 <A>을 X축에 대하여 \alpha만큼, Y축에 대하여 beta만큼 회전을 시키면 Z축과 일치하게 됩니다.
<A>을 Z축에 일치시킨 후에 Z축을 원하는 각도만큼(여기서는 \theta라고 하자.)회전을 하면 됩니다.
CIsVect3d::GetAngleToZAxis(double &alpha, double &beta) const { CIsVect2d vec1(m_dy , m_dz); CIsVect2d vec2(0 , 1); try { alpha = 0; vec1.Normalize(); alpha = acos(vec1.DotProduct(vec2)); double cross = vec1 * vec2; if(cross < 0) alpha = -alpha; } catch(...) { } const double d = sqrt(m_dy * m_dy + m_dz * m_dz); vec1.Set(m_dx , d); try { beta = 0; vec1.Normalize(); beta = acos(vec1.DotProduct(vec2)); double cross = vec2 * vec1; // reverse cross product if(cross < 0) beta = -beta; } catch(...) { } }
댓글
댓글 쓰기