목표
- 삼각함수 sin, cos, tan 이해
- 각도법(degree)와 호도법(radian) 간의 관계
- 회전변환을 이용한 특정 벡터의 회전
- 삼각함수의 역함수 asin, acos, atan와 atan2 함수
- 극 좌표계
들어가기 전
본 글에서 직접적으로 설명하지 않지만, 언급하고 있는 내용입니다.
- 역함수와 전단사
- 표준 기저 벡터
인프런 강의 중 이득우의 게임엔진을 지탱하는 게임수학을 참고하여 작성되었습니다.
삼각함수
삼각비(Trigonometric Ratio)
직각 삼각형의 ‘한 내각에 대응하는 어느 두 변의 비율(비)

- $sin=\frac{Opposite}{Hypotenuse}$: 각 세타에 대한 높이/빗변의 값
- $cos=\frac{Adjacent}{Hypotenuse}$: 각 세타에 대한 밑변/빗변의 값
- $tan=\frac{Opposite}{Adjacent}$: 각 세타에 대한 높이/밑변의 값
sin(30도) = 0.5 // 높이 = 빗변의 절반
cos(0도) = 0 // 밑변 = 빗변과의 비율 0 (세타가 0도일 때, 밑변이 존재하지 않음)
cos(90도) = 1 // 밑변 = 빗변과의 비율 1 (밑변 = 빗변)
삼각함수(Trigonometric Function)
각의 크기를 삼각비로 나타내는 함수, 삼각형의 각도와 변의 길이의 관계를 나타낸 것
삼각비를 집합의 관점에서 대응 관계로 나타낸 것
삼각함수는 평면의 모든 각($0^{\circ}$ ~ $360^{\circ}$의 배수)에 대해 일반화시킨 대응관계
(함수: 정의역의 모든 원소가 공역의 한 원소에 대응되는 관계)
- 정의역: 실수 집합 $\mathbb{R}$ (모든 실수)
- 공역: [-1, 1] // -1과 1을 포함하는 범위
- y = sin(x): 삼각비에 어떤 정의역의 값을 대입하면 -1 ~ 1 사이의 값이 나온다는 뜻

1. y = sin(x)
삼각함수 y = sin(x)는 각도가 x일 때, 단위원 위에서 y축의 크기를 나타냄.
즉, 각도에 따른 y 좌표를 함수로 나타낸 것이다.
입력값으로 각도가 주어질 때, 출력값이 어떻게 변하는지를 관찰하기 위함.
2. 왜 삼각함수의 공역은 -1 ~ 1 범위인가?
단위 원
삼각함수에서 중심이 원점이고 반지름의 길이가 1인 원
평면을 모두 커버하는 단위원을 중심으로 삼각함수를 분석한다.

삼각 함수 그래프
각(세타)에 따른 삼각비의 값을 그래프로 나타낸 것 (범위: -1 ~ 1)


※ Notice
삼각함수는 2π(=180°) 단위로 반복(주기성)되기 때문에 90° 와 -270° 는 부호가 다름. (코사인과 사인 함수의 성질 참고)
따라서, 회전 시 올바른 값을 얻기 위해선 0°~360°도 사이의 각으로 정규화하는 것이 좋음.
회전변환 x∙(cosθ,sinθ) + y∙(-sinθ, cosθ) 사용 시 -θ를 사용해도 올바른 값 얻어짐.
코사인과 사인 함수의 성질
- 사인 함수와 코사인 함수는 항상 [-1, 1] 범위를 일정하게 반복하는 패턴을 가짐.
- 사인과 코사인 함수는 2π(=180°) 단위로 반복됨.
- y축을 기준으로 좌우를 포갰을 때 아래 식과 같은 값을 가진다.
- 코사인 함수는 동일하게 겹치는 좌우 대칭임.
- 사인 함수는 상하가 반전된 형태를 가짐.


(출처: 삼각 함수 - 위키백과, 우리 모두의 백과사전)
탄젠트 함수의 성질
탄젠트 함수는 $cos90^{\circ}, cos270^{\circ}$에서 존재하지 않음.
탄젠트의 분모인 𝑐𝑜𝑠𝜃에 0이 오면 안되기 때문.

(출처: 삼각 함수 - 위키백과, 우리 모두의 백과사전)
삼각함수의 유용한 공식
직각 삼각형 = 피타고라스의 정리
단위원이 아닌 경우에도 아래 공식은 성립한다.

원의 반지름 값이 $r$인 경우, 원호의 좌표는 $(cos\theta, sin\theta)$ 벡터에 $r$배 한 결과가 나온다.

값의 측정
1. 각도법(Degree)
원을 360개로 균일하게 나누고 $^{\circ}$를 사용해 각을 표현함.
2. 호도법(Radian)
컴퓨터에서 수학을 전개할 때 편리하게 사용하기 위한 단위
2.1. 반지름이 1인 원호를 오른쪽으로 쫙 펴지면 무리수 $\pi$가 나온다.


2.2. \pi중에서 반지름과 원호가 1인만큼 거꾸로 되감았을 때, 나오는 각도가 호도법의 단위인 라디안(rad)이다.

호도법과 각도법의 관계
180도(각도법)은 라디안(약 57.3도)를 $\pi$만큼 곱한 값이다.


벡터의 회전(Rotation of Vector)
회전 변환
어떤 물체(정점)를 각 세타만큼 회전시키기 위해 진행되는 메커니즘
회전 변환 조건
회전 변환은 아래 3가지를 유지한 상태로 변형하는 것이다.
- 새로운 벡터를 만들기 위해 필요한 두 벡터의 크기가 1
- 두 벡터는 직교
- 두 벡터는 현재 방향을 유지
새로운 벡터(x, y)를 만들기 위해서 실벡터공간$\mathbb{R}^2$의 표준기저벡터인 (1,0)과 (0,1)을 사용하는 방법

표준 기저벡터를 사용한 실벡터공간 \mathbb{R}^2의 원소 (x,y)의 생성 방법
벡터(x,y)를 세타만큼 회전하기 위해선, 회전 변환 조건에 따라 표준 기저 벡터가 필요함으로 아래와 같이 표현할 수 있다.

회전변환 시각화
아래는 벡터(1,1)을 세타만큼 회전시키기 위해 진행되는 회전 변환이다.
- 두 기저 벡터는직교 상태를 유지하기 위해 각각 동일한 각도만큼 회전한다.
- 단위원 기준 회전 변환으로 생성한 벡터는 (cos - sin, sin + cos)이다.



회전변환 예시
벡터 (1,0)을 θ만큼 회전한다면?
(cos θ, sin θ)로 회전한 위치를 구할 수 있다.
벡터 (0, 1)를 θ만큼 회전한다면?
(-sin θ, cos θ)로 회전한 위치를 구할 수 있다.
벡터(5, 7)를 θ만큼 회전한다면?
회전 변환을 사용하여 회전한 위치를 구해야 한다.
회전 변환의 조건의 성립하기 위해 벡터를 두 표준 기저 벡터를 사용하여 나타낸다.
v(5, 7) = 5*(1,0) + 7*(0,1)
회전 변환을 적용하면, 임의의 벡터가 세타만큼 회전했을 생성되는 새로운 벡터를 얻을 수 있다.
v'(5,7) = 5*(-sin세타, cost세타) + 7*(cos세타, sin세타)
= (5*-sin세타 + 7*cos세타, 5*cos세타 +7*sin세타)
삼각함수의 역함수 (Inverse trigonometric functions)
역함수란?
정의역과 공역을 뒤집은 함수
역함수 조건
역함수가 존재하기 위해서는 해당 함수는 전단사 함수여야 한다.
$sin, cos, tan$는 전단사함수가 아니다.
- 단사 X: 모든 각(x)에 대하여 y가 여러번 대응되기 때문임. (1:1 대응이 아님.)
- 전사 O: 공역(y)를 [-1, 1]로 범위 제한 시 공역 = 치역이기 때문에 전사는 만족함.
→ 단사 함수로 만들기 위해 의도적으로 정의역의 값을 제한시켜 역함수를 존재시킨다.
역함수가 되기 위한 정의역 구간
- 사인 함수가 전단사 함수가 될 수 있는 정의역 구간은? : $[-\frac{\pi}{2}, \frac{\pi}{2}]$ // [$-90^{\circ}$, $90^{\circ}$]
- 코사인 함수가 전단사 함수가 될 수 있는 정의역 구간은? : $[0, \pi]$ // [ $0^{\circ}$, $180^{\circ}$]
- 탄젠트 함수가 전단사 함수가 될 수 있는 정의역 구간은? $(-\frac{\pi}{2}, \frac{\pi}{2})$ // ( $-90^{\circ}$, $90^{\circ}$)


아크사인, 아크코사인, 아크탄젠트
위의 범위로 정의역을 제한시켜 정의한 역함수를 아크사인, 아크코사인, 아크탄젠트 함수라고 부른다.

역함수가 다루는 각의 범위
역함수는 함수의 정의역과 공역(치역)이 뒤바뀐 함수이기 때문에,
역함수의 공역은 역함수를 만들기 위해 제한했던 함수의 입력 각 범위와 동일하게 나온다.
- arcsin: [$-90^{\circ}$, $90^{\circ}$] → 제 1사분면, 4사분면
- arccos: [ $0^{\circ}$, $180^{\circ}$] → 제 1사분면, 2사분면
- arctan: ( $-90\^{\circ}$, $90^{\circ}$) → 제 1사분면, 4사분면
삼각함수의 역함수를 구하는 이유는?
우리가 sin/cos/tan의 값을 알고 있을 때, 그 값이 몇 도인지 파악하는 데 유용하게 사용함.
다만, 역함수는 제 3사분면의 각도는 제공하지 않기 때문에 값에 대 해 얻은 각도가 +인지 -인지 구분할 수 가 없다. 따라서 이를 구분하여 제 3사분면의 각을 얻기 위해 atan2 함수를 사용한다.

atan2(y, x)
값과 두 부호를 제공하여 제 3사분면을 포함한 평면 상의 모든 각도 (-180, 180) 범위의 값을 얻어내는 함수

(출처: [프로그래밍 이론] 두 점 사이의 절대각도를 재는 atan2)
1. atan과 atan2의 차이
atan 함수는 인자값으로 부호 구분 없이 값만 받기 때문에 제 1사분면과 제 3사분면 중 어디서 얻은 값인지 알 수가 없고, [$-90^{\circ}, 90^{\circ}$] 범위의 값을 반환한다.
만약, 값이 양수인데 축의 부호가 하나라도 음수인 것을 안다면, 이는 축이 둘 다 음수인 제 3분면에 해당한다는 사실을 알 수 있다.
따라서, atan2는 값뿐만 아니라 축의 부호도 인자값으로 받아 평면 상의 모든 각도 [$-180^{\circ}, 180^{\circ}$]를 얻어낼 수 있다.
→ 어떤 벡터의 각( $e_1$과 벡터 사이의 각도)을 알고싶다면 탄젠트의 역함수 atan2를 사용한다.
1.1. atan2가 (-180도, 180도) 범위를 제공할 수 있는 이유
atan은 tan 함수의 역함수이기 때문에 공역이 ($-90^{\circ}, 90^{\circ}$) 으로 제한 받는다. (전단사 만족을 위해 tan 함수의 정의역을 제한했기 때문)
atan2는 tan 함수의 역함수가 아니라 y와 x의 두 입력 값을 받아 각도를 계산하는 함수이므로 ($-180^{\circ}, 180^{\circ}$) 범위를 제공이 가능하다.
즉, atan은 역함수이고 atan2는 역함수처럼 동작하지만 실상은 역함수가 아니다.
1.2. 예시
-135도와 45도의 삼각함수 tan의 값은 1로 동일하다.
즉, 역함수 atan에 값 1만 제공하면 공역이 ($-90^{\circ}, 90^{\circ}$) 범위이기 때문에 무조건 45도를 반환해서 정확히 알 수가 없다.
따라서 atan2에 x(=cos세타), y(=sin세타)를 제공하여 부호를 제공함으로써,
atan2는 내부에서 삼각비를 구하고 해당 값을 통하여 부호에 따라 알맞은 각도를 반환한다. ($-180^{\circ}, 180^{\circ}$) 범위 제공


2. atan2의 반환 범위
- atan은 -파이/2 ~ 파이/2의 라디안 값으로 반환함.
- atan2는 [$0^{\circ}, 180^{\circ}$], [$0^{\circ}, 180^{\circ}$] 반환함.

(출처: [프로그래밍 이론] 두 점 사이의 절대각도를 재는 atan2)
3. 라디안 → 디그리 변환
삼각함수(sin, cos,tan)와 역삼각함수(asin…)는 라디안을 기본 단위로 사용한다.
따라서, 디그리 각도를 얻기 위해서는 라디안을 디그리로 변환해야 한다.
1. 수식 사용 (1라디안 = 180도/파이)
double radian = atan2(y, x);
double degree = radian * (180 / 파이)
2. 함수 사용
double degree = degree(atan2(y, x));
극 좌표계(Polar Coordinate)
극 좌표계
평면은 사실 수많은 원으로 구성되어 있다는 개념으로, 원호 위의 한 점을 (반지름, 세타)로 표현한 좌표
회전을 할 때 주로 데카르트 좌표계를 사용하지만 회전을 편리하게 하기 위해서 일시적으로 극좌표계로 변환하여 사용하기도 한다.

데카르트 좌표계 → 극 좌표계 변환

극 좌표계 → 데카르트 좌표계 변환

극 좌표계 활용 예시
사각형으로 구성되어 있는 변환을 중심에서 멀어질수록 더 많이 회전을 시키는 예시이다.
극 좌표계로 변환한 다음에 극 좌표계의 반지름값이 비례할 수록 입력에 따라서 변화되는 세타를 점점 더 많이 주면 된다.
즉, 반지름(r)이 클수록 세타()를 많이 주면 끝으로 갈수록 회전률이 높아져 소용돌이 치는 효과를 얻을 수 있다.
list<pair<int, int>> RotationList;
for(const pair<int, int>& Point: PointList)
{
// 데카르트 -> 극 좌표계
double r = sqrt(Point.x, Point.y);
double theta = atan2(Point.y, Point.x);
theta += time * r; // 시간의 흐름에 따라 각도가 커져 회전하게 됨. 이때, r이 클수록 각도는 더 많이 들어감.
// 극 좌표계 -> 데카르트
pair<int, int> RotPoint;
RotPoint.x = r * cos(theta);
RotPoint.y = r * sin(theta);
RotationList.emplace_back(RotPoint);
}

'수학' 카테고리의 다른 글
| [기초 수학] 행렬과 역행렬 (0) | 2025.01.02 |
|---|---|
| [기초수학] 선형성 (0) | 2024.12.30 |
| [게임수학] 부동소수점 (0) | 2023.10.29 |
| [게임수학] 베지어 곡선 (0) | 2023.08.12 |
| [게임수학] 보간법, 선형 보간법 (0) | 2023.06.03 |