매트랩 각도 구하기 - maeteulaeb gagdo guhagi

반응형

두 점 사이의 절대각도를 재는 atan2

프로그래밍 언어에서 역탄젠트를 계산하는 함수 atan2의 특징을 알아보자

아크탄젠트란?

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
삼각비

아크탄젠트(arctangent)는 역탄젠트라고도 하며 탄젠트의 역함수이다. 아크탄젠트를 이용하면 위 사진에서의 θ의 각도를 구할 수 있다.

모든 프로그래밍 언어에는 아크탄젠트를 계산할 수 있도록 Math 모듈에 atan(y / x)과 atan2(y, x) 함수를 지원한다.


atan과 atan2의 차이점

atan과 atan2은 두 점 사이의 θ의 절대각을 구하는 함수인데 왜 두가지로 나뉘었을까?

 

atan은 두 점 사이의 탄젠트값을 받아 절대각을 -π/2 ~ π/2의 라디안 값으로 반환한다. (-90 ~ 90도)

 

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
atan2의 리턴값 범위

atan2는 두 점 사이의 상대좌표(x, y)를 받아 절대각을 -π ~ π의 라디안 값으로 반환한다. (-180 ~ 180도)


atan2을 사용하는 이유

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
데카르트 좌표계에서 atan2를 적용한 모습

+- 극이 표시되는 데카르트 좌표계에서 사용할 때 유용하다.

atan2 함수는 점 A로부터 점 B가 상대적으로 어느 위치에 있는지를 파라미터로 받는데, 상대적인 위치이기 때문에 파라미터 x나 y가 음수값이 될 수 있다.

하지만 atan 함수를 사용한다면 파라미터가 직선의 기울기이므로 결과값은 방향 개념이 상실된 두 점 사이의 각도가 되어버린다.


예시

아래 예시들은 자바스크립트로 작성하였다.

b가 a보다 {2, 2} 만큼 위치한 경우

const a = {
    x : 0,
    y : 0
};
const b = {
    x : 2,
    y : 2
};

const x = b.x - a.x;
const y = b.y - a.y;

const radian = Math.atan2(y, x);
const degree = radian * 180 / Math.PI // 라디안 -> 디그리 변환

console.log(radian);
console.log(degree);

 

0.7853981633974483
45

b가 a보다 {-2, -2} 만큼 위치한 경우

const a = {
    x : 0,
    y : 0
};
const b = {
    x : -2,
    y : -2
};

const x = b.x - a.x;
const y = b.y - a.y;

const radian = Math.atan2(y, x);
const degree = radian * 180 / Math.PI // 라디안 -> 디그리 변환

console.log(radian);
console.log(degree);

 

-2.356194490192345
-135

 

반응형

공유하기

게시글 관리

구독하기Spiral Moon's programming blog

저작자표시 비영리

  • 카카오스토리
  • 트위터
  • 페이스북

'Programming > 프로그래밍 이론' 카테고리의 다른 글

[프로그래밍 이론] In-app browser, External browser  (1)2020.07.03[프로그래밍 이론] 반각문자 @와 전각문자 @  (1)2019.10.10[프로그래밍 이론] JWT (Json Web Token)  (0)2019.04.19[디자인 패턴] 팩토리 메소드 패턴 (Factory method pattern)  (0)2019.03.20[디자인 패턴] 복합체 패턴 (Composite pattern)  (0)2019.03.12

두 직선이 이루는 각 또는 두 벡터가 이루는 각을 구하는 문제는 영상처리나 각종 프로그래밍을 하다보면 필요한 경우가 많습니다. 그런데 그때마다 식을 세우는 것은 좀 번거롭기 때문에 이곳에 정리해 두고 참고하려 합니다.

풀고자 하는 문제는 다음의 두가지 입니다.

  • 두 벡터 v1, v2 사이의 ±회전각: 벡터 v1이 v2로 변했다고 했을 때 몇 도나 회전했고 또 어떤 방향으로(+, -) 회전했는지 계산
  • 두 직선 L1과 L2가 이루는 각: 두 점 (a1,b1), (a2,b2)를 지나는 직선 L1과 두 점 (c1,d1), (c2,d2)를 지나는 직선 L2가 이루는 사이각

두 벡터가 이루는 절대적인 사이각은 비교적 쉽게 구할 수 있지만 v1이라는 벡터가 v2로 변했을 때, 몇 도나 움직였고 또 어떤 방향으로(시계방향? 반시계방향?) 변했는지까지 알아내려면 머리가 조금 복잡해 집니다 (카메라의 팬, 틸트 구할 때, 비행체의 pitch, roll, yaw 구할 때 등). 또 직선의 경우에는 사이각이 2가지가 나올 수 있기 때문에 햇갈릴 소지가 있습니다.

☞ '사이각'이 맞는 걸까요? 아님 '사잇각'이 맞는 걸까요. 햇갈리네요..

위 계산은 기본적으로 벡터의 내적 또는 외적을 이용하기 때문에 벡터의 내적, 외적 수식을 먼저 적어봅니다.

1. 벡터의 내적

두 벡터 v1 = (x1,y1), v2 = (x2,y2)에 대해 그 사이각을 θ라 했을 때, 두 벡터의 내적(inner product 또는 dot product)는 다음과 같이 정의됨

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
 --- (1)

식 (1)에서 x1x2 + y1y2 = |v1||v2|cosθ 가 성립함을 알 수 있음 (단, |v|는 벡터 v의 크기).

2. 벡터의 외적

벡터의 외적은 기본적으로 3차원에서 정의되며 두 벡터를 v1 = (x1,y1,z1), v2 = (x2,y2,z2)라 했을 때, 두 벡터의 외적(cross product)는 다음과 같이 정의됨

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
 --- (2)

단, i=(1,0,0), j=(0,1,0), k=(0,0,1)는 좌표축 단위벡터.

벡터의 내적은 좌표 성분끼리 모두 곱하여 합한 것이므로 결과적으로 하나의 상수값이 나오지만, 벡터의 외적은 식 (2)와 같이 3차원의 새로운 벡터가 된다는 점에서 큰 차이가 있음.

기하학적으로 봤을 때, 외적 v1 × v2는 v1, v2로 이루어지는 평면에 수직이면서 그 크기가 (v1, v2로 이루어지는 평행사변형의 넓이인) |v1||v2|sinθ인 벡터로서 그 방향은 아래 그림과 같음:

매트랩 각도 구하기 - maeteulaeb gagdo guhagi

<그림 1> 벡터의 외적  

☞ 벡터의 외적 방향이 위쪽인지 아래쪽인지 햇갈리기 쉽기 때문에 보통 오른손 법칙, 왼손 법칙 등으로 설명하는데 이게 오른손인지 왼손인지도 햇갈릴 수가 있습니다. 따라서 저는 그냥 첫번째 벡터를 x축, 두번째 벡터를 y축으로 생각했을 때 두 벡터의 외적은 z축 방향이라고 생각합니다. 이와 같이 생각해보면 위 그림에서 v1 × v2는 위쪽 방향, v2 × v1은 아래쪽 방향이 됨을 쉽게 알 수 있습니다.

☞ 벡터의 외적은 원래 3차원 공간에서 정의되지만 z = 0이라고 생각하면 2D 평면에서도 계산은 가능합니다. 즉, 두개의 2차원 벡터 (x1,y1), (x2,y2)에 대해 외적을 (x1,y1,0) × (x2,y2,0) = (0, 0, x1y2-y1x2)와 같은 식으로 계산할 수 있습니다. 결과로 나온 외적 z좌표의 크기 및 부호를 이용하면 2차원 평면에서도 두 벡터가 이루는 각, 각의 방향, 평행사변형 넓이 등을 손쉽게 계산할 수 있음을 알 수 있습니다.

☞ 참고로 영벡터가 아닌 두 벡터의 외적이 영벡터가 되는 경우는 두 벡터가 같은 방향이거나 또는 서로 반대 방향인 경우입니다.

3. 두 벡터의 사이각(회전각)

2차원 평면에서 두 벡터 v1 = (x1,y1), v2 = (x2,y2)가 이루는 각 및 각의 방향(시계방향, 반시계방향)은 다음과 같이 계산됨 (θ가 +면 v1->v2는 반시계방향, -면 시계방향).

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
 --- (3)

3차원 공간에서는 어떤 방향에서 봤느냐(이쪽에서 봤는지 반대편에서 봤는지)에 따라서 회전의 방향이 서로 반대가 될 수 있기 때문에 각의 방향을 부호로서 정할 수가 없음. 따라서 3차원에서는 두 벡터 v1 = (x1,y1,z1), v2 = (x2,y2,z2)의 절대적인 사이각은 내적을 이용하여 구하고 각의 방향은 외적 벡터의 방향을 보고 따로 판단해야 함. 두 벡터의 (부호가 없는) 절대적인 사이각은 다음과 같이 계산됨:

매트랩 각도 구하기 - maeteulaeb gagdo guhagi
 --- (4)

4. 두 직선의 사이각

직선의 경우에는 아래 그림과 같이 어떻게 벡터를 잡느냐에 따라서 서로 다른 2개의 사이각이 나올 수 있기 때문에 보통은 최소 사이각을 계산하는 것이 일반적임.

매트랩 각도 구하기 - maeteulaeb gagdo guhagi

<그림 2> 직선의 사이각

직선 L1 상의 임의의 두 점 (a1,b1), (a2,b2)에 대한 벡터를 v1 = (a2-a1, b2-b1), 직선 L2 상의 임의의 두 점 (c1,d1), (c2,d2)에 대한 벡터를 v2 = (c2-c1, d2-d1)라 할 때, 두 직선 L1과 L2의 최소 사이각은 v1, v2의 사이각을 θ1라 할 때, θ1와 π - θ1 중 작은 값.