Computer >> 컴퓨터 >  >> 프로그래밍 >> C++

C++에서 다른 점을 중심으로 점 회전 구현하기


원점을 중심으로 점 X를 반시계 방향으로 각도 θ만큼 회전시키는 연산은 복소수 곱셈을 이용해 간단하게 처리할 수 있습니다.

원점 기준 반시계 방향 θ 회전: X * polar(1.0, θ)

여기서 사용되는 polar 함수는 <complex> 헤더 파일에 정의되어 있으며, 크기(magnitude)와 편각(phase angle)을 인자로 받아 해당하는 복소수를 생성합니다. 즉, polar(mag, angle)는 크기 mag와 각도 angle을 가진 복소수를 반환하며, 크기가 1인 경우 단위 회전 복소수(cosθ + i·sinθ)가 되어 곱셈만으로 회전 변환이 가능합니다.

점 Y를 중심으로 점 X 회전하기

한 점을 다른 점을 중심으로 회전시키려면 평행이동(translation) 개념을 활용해야 합니다. 평행이동이란 모든 좌표를 특정 방향으로 일괄 이동시키는 변환을 의미합니다.

회전 절차

  • 1단계 — 좌표계 이동: 모든 점에서 Y를 빼서 Y를 새로운 원점으로 만듭니다. 이때 X는 X−Y가 됩니다.

  • 2단계 — 회전 적용: 새로운 원점을 기준으로 앞서 소개한 공식을 적용해 (X−Y)를 회전시킵니다. → (X−Y) * polar(1.0, θ)

  • 3단계 — 역평행이동: 모든 점에 Y를 다시 더해 원래 좌표계로 되돌립니다.

최종 공식: Y를 중심으로 X를 회전한 결과 = (X − Y) * polar(1.0, θ) + Y

예제 코드

아래 코드는 한 점을 다른 점을 중심으로 회전시키는 과정을 보여줍니다. typedef complex<double> point로 복소수 타입을 점(point)처럼 다루고, 매크로를 통해 실수부와 허수부를 x, y 좌표로 직관적으로 접근할 수 있습니다.

#include <iostream>
#include <complex>
using namespace std;
typedef complex<double> point;
#define x real()
#define y imag()
int main(){
    // Q를 중심으로 P 회전
    point X(5.0, 3.0);
    point Y(2.0, 4.0);
    // 회전 각도는 90도
    double theta = 3.14/2;
    point Xnew = (X-Y) * polar(1.0, theta) + Y;
    cout << "X를 Y를 중심으로 반시계 방향 90도 회전한 결과:";
    cout << "(" << Xnew.x << ", " << Xnew.y << ")" << endl;
    return 0;
}

실행 결과

X를 Y를 중심으로 반시계 방향 90도 회전한 결과:(3.00239, 6.9992)

출력값에서 소수점 오차가 발생하는 이유는 π를 근사값 3.14로 사용했기 때문입니다. M_PI 상수나 더 정밀한 파이 값을 사용하면 (3, 7)에 가까운 정확한 결과를 얻을 수 있습니다. 이처럼 복소수의 극형식 표현을 활용하면 삼각함수 계산 없이도 2D 회전 변환을 깔끔하게 구현할 수 있습니다.