이 문제에서는 2차원 평면 위의 한 점 P와 직선 방정식 ax + by + c = 0의 계수 a, b, c가 주어집니다. 우리가 해야 할 일은 이 직선을 거울 삼아 점 P의 대칭점, 즉 거울상(mirror image)을 구하는 것입니다.
문제 이해를 돕는 예시
입력
P = (2, 1), a = 1, b = -1, c = 0
출력
(1, 2)
설명
주어진 계수로 만들어지는 직선은 x − y = 0, 즉 y = x입니다. 점 (2, 1)을 이 직선을 기준으로 반사하면 대칭 위치에 있는 (1, 2)를 얻게 됩니다.
풀이 접근 방식
핵심은 거울상이 될 점 P'(x', y')의 좌표를 구하는 것입니다. 점 P에서 P'로 이어지는 선분이 거울 직선과 만나는 교점을 R이라고 하면, 다음 두 가지 성질이 성립합니다.
- R은 선분 PP'의 중점이다.
- 직선 P–R–P'는 거울 직선에 수직이다.
거울 직선 ax + by + c = 0에 수직인 직선의 방정식은 bx − ay + d = 0 형태로 쓸 수 있으며, 점 P(x, y)와 R(xm, ym) 사이의 관계를 정리하면 아래와 같은 공식을 얻습니다.
d = −2 × (ax + by + c) / (a² + b²)
이 값 d를 이용하면 거울상의 좌표는 다음과 같이 간단히 계산됩니다.
x' = x + a × d
y' = y + b × d
즉, 복잡한 연립방정식을 풀 필요 없이 점과 직선 사이의 거리 항을 활용해 한 번의 연산으로 대칭점을 구할 수 있으며, 시간 복잡도는 상수 시간 O(1)입니다.
C++ 구현 예제
#include <iostream>
using namespace std;
// 거울상 좌표를 계산하는 함수
void findMirrorImage(double a, double b, double c, double x, double y){
// 점과 직선의 위치 관계를 나타내는 값 d 계산
double points = -2 * (a * x + b * y + c) / (a * a + b * b);
double xm = points * a + x; // x' 좌표
double ym = points * b + y; // y' 좌표
cout<<"("<<xm<<","<<ym<<")";
}
int main(){
double a = -1.0;
double b = 1.0;
double c = 0.0;
double x = 1.0;
double y = 0.0;
cout<<"Image of point ("<<x<<", "<<y<<") using mirror ("<<a<<")x + ("<<b<<")y + ("<<c<< ") = 0, is :";
findMirrorImage(a, b, c, x, y);
return 0;
}실행 결과
Image of point (1, 0) using mirror (-1)x + (1)y + (0) = 0, is :(0,1)
마무리
이처럼 직선 ax + by + c = 0에 대한 점의 거울상은 '수직 관계'와 '중점 성질' 두 가지만 활용하면 간단한 공식으로 구할 수 있습니다. 컴퓨터 그래픽스의 반사 변환, 게임의 충돌 처리 등 다양한 분야에서 응용되는 기본 개념이므로, 공식의 유도 과정과 함께 이해해 두면 큰 도움이 됩니다.