>백엔드 개발 >C++ >2D 공간과 3D 공간 모두에서 두 벡터 사이의 시계 방향 각도를 효율적으로 계산하려면 어떻게 해야 합니까?

2D 공간과 3D 공간 모두에서 두 벡터 사이의 시계 방향 각도를 효율적으로 계산하려면 어떻게 해야 합니까?

Patricia Arquette
Patricia Arquette원래의
2024-11-21 07:44:09861검색

How can I efficiently calculate the clockwise angle between two vectors in both 2D and 3D space?

벡터 사이의 시계 방향 각도를 효율적으로 계산

전통적으로 내적을 활용하여 두 벡터 사이의 각도를 계산했는데, 이는 내부 각도를 결정합니다. 0~180도 범위. 그러나 이 접근 방식은 각도와 그 보수 사이의 적절한 결과를 결정할 때 문제가 됩니다.

시계 방향 각도를 계산하는 더 직접적인 방법이 있습니까?

2D 케이스

내적이 각도의 코사인과 관련되는 것과 마찬가지로 행렬식은 사인에 비례합니다. 이 관계를 통합하면 다음과 같이 각도를 계산할 수 있습니다.

dot = x1 * x2 + y1 * y2  # Dot product between [x1, y1] and [x2, y2]
det = x1 * y2 - y1 * x2  # Determinant
angle = atan2(det, dot)  # atan2(y, x) or atan2(sin, cos)

계산된 각도의 방향은 좌표계의 방향과 일치합니다. x가 오른쪽을 가리키고 y가 아래를 가리키는 왼손 좌표계에서 시계 방향 각도는 양수 값을 생성합니다. 반대로, y가 위를 가리키는 수학적 좌표계에서 결과는 수학에서 관례적인 것처럼 반시계 방향 각도를 반영합니다. 입력 벡터의 순서를 바꾸면 부호가 변경되어 결과의 부호를 수정할 수 있는 유연성이 제공됩니다.

3D 사례

3차원에서 임의의 벡터는 자체 축을 정의합니다. 양쪽에 수직으로 회전합니다. 이 축은 고정된 방향을 가지지 않기 때문에 회전 각도의 방향을 고유하게 결정하는 것은 불가능합니다. 일반적인 규칙은 양의 각도를 할당하고 이 규칙에 맞게 축을 정렬하는 것입니다. 이러한 맥락에서 정규화된 벡터의 내적은 각도 계산에 충분합니다.

dot = x1 * x2 + y1 * y2 + z1 * z2  # Between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1 * x1 + y1 * y1 + z1 * z1
lenSq2 = x2 * x2 + y2 * y2 + z2 * z2
angle = acos(dot / sqrt(lenSq1 * lenSq2))

3D에 포함된 평면

알려진 법선이 있는 평면 내에 제한된 벡터의 경우 벡터 n에는 고려해야 할 특별한 경우가 있습니다. 회전축은 n과 일치하고 n의 방향은 축의 방향을 고정합니다. 이 시나리오에서는 행렬식에 n을 포함하도록 위의 2D 계산을 수정하여 3x3 행렬로 변환할 수 있습니다.

dot = x1 * x2 + y1 * y2 + z1 * z2
det = x1 * y2 * zn + x2 * yn * z1 + xn * y1 * z2 - z1 * y2 * xn - z2 * yn * x1 - zn * y1 * x2
angle = atan2(det, dot)

이 계산이 유효하려면 법선 벡터 n을 단위로 정규화해야 합니다. 길이.

또는 행렬식을 삼중 곱으로 표현할 수 있습니다.

det = n · (v1 × v2)

이 접근 방식은 일부 API에서 구현하기가 더 쉬울 수 있으며 기본 메커니즘에 대한 통찰력을 제공합니다. 는 각도의 사인에 비례하고 평면에 수직입니다. 즉, n의 배수입니다. 따라서 내적은 기본적으로 올바른 부호가 적용된 벡터의 길이를 측정합니다.

범위 0 – 360°

대부분의 atan2 구현은 범위 내에서 각도를 반환합니다. [-π, π](라디안) 또는 [-180°, 180°](도). [0, 2π] 또는 [0°, 360°] 내의 양의 각도를 얻으려면 다음 변환을 적용할 수 있습니다.

dot = x1 * x2 + y1 * y2  # Dot product between [x1, y1] and [x2, y2]
det = x1 * y2 - y1 * x2  # Determinant
angle = atan2(det, dot)  # atan2(y, x) or atan2(sin, cos)

또는 다음 표현식은 대소문자 구분을 피합니다.

dot = x1 * x2 + y1 * y2 + z1 * z2  # Between [x1, y1, z1] and [x2, y2, z2]
lenSq1 = x1 * x1 + y1 * y1 + z1 * z1
lenSq2 = x2 * x2 + y2 * y2 + z2 * z2
angle = acos(dot / sqrt(lenSq1 * lenSq2))

이 수정 기술은 이 특정 문제에만 국한되지 않고 atan2와 관련된 모든 시나리오에 적용할 수 있습니다.

위 내용은 2D 공간과 3D 공간 모두에서 두 벡터 사이의 시계 방향 각도를 효율적으로 계산하려면 어떻게 해야 합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.