3D 공간에서 두 평면 사이의 각도를 구하는 방법을 배우기 전에, 먼저 평면과 각도라는 기본 개념부터 짚고 넘어가겠습니다.
기본 개념
평면(Plane)은 무한히 뻗어 있는 2차원 표면을 의미합니다.
각도(Angle)는 한 점에서 서로 교차하는 두 직선 또는 두 표면 사이가 이루는 도(degree) 단위의 공간을 말합니다.
따라서 이 문제에서는 3D 공간에서 서로 교차하는 두 평면이 이루는 각도를 구해야 합니다. 즉, 서로 만나는 두 평면이 교차하는 지점에서 형성되는 각도를 찾는 것이 목표입니다.
두 평면 사이의 각도 구하는 원리
두 3D 평면 사이의 각도를 계산하려면, 각 평면의 법선 벡터(normal vector) 사이의 각도를 구하면 됩니다. 두 평면이 이루는 각도는 곧 두 법선 벡터가 이루는 각도와 같기 때문입니다.
여기서 두 평면은 다음과 같이 주어집니다.
p1 : ax + by + cz + d = 0
p2 : hx + iy + jz + k = 0
평면 p1과 p2의 법선 벡터 방향은 각각 (a, b, c)와 (h, i, j)입니다.
두 법선 벡터 사이의 각도를 구하기 위한 수학적 공식은 다음과 같습니다.
Cos Ø = {(a*h) + (b*i) + (c*j)} / [(a2 + b2 + c2) * (h2 + i2 + j2)]1/2
Ø = Cos-1 { {(a*h) + (b*i) + (c*j)} / [(a2 + b2 + c2) * (h2 + i2 + j2)]1/2 }즉, 두 법선 벡터의 내적(dot product)을 각 벡터 크기의 곱으로 나눈 값의 역코사인(acos)을 취하면 두 평면 사이의 각도를 얻을 수 있습니다. 결과는 라디안 단위로 나오므로, 도(degree) 단위로 변환하려면 180/π를 곱해 주어야 합니다.
C++ 예제 코드
#include <iostream>
#include <math.h>
using namespace std;
int main() {
float a = 2;
float b = 2;
float c = -1;
float d = -5;
float h = 3;
float i = -3;
float j = 5;
float k = -3;
float s = (a*h + b*i + c*j); // 두 법선 벡터의 내적
float t = sqrt(a*a + b*b + c*c); // 첫 번째 법선 벡터의 크기
float u = sqrt(h*h + i*i + j*j); // 두 번째 법선 벡터의 크기
s = s / (t * u);
float pi = 3.14159;
float A = (180 / pi) * (acos(s)); // 라디안을 도 단위로 변환
cout<<"Angle is "<<A<<" degree";
return 0;
}
실행 결과
Angle is 104.724 degree
위 코드에서 변수 d와 k는 각 평면의 상수항으로, 두 평면 사이의 각도 계산에는 영향을 주지 않습니다. 각도는 오직 법선 벡터의 방향 성분인 (a, b, c)와 (h, i, j)에 의해서만 결정됩니다.