이 글에서는 방정식을 활용하여 평면 위의 세 점 a, b, c로 정의된 원을 기준으로, 점 d가 해당 원의 내부에 속하는지 아니면 외부에 속하는지 판별하는 C++ 프로그램을 소개합니다. 판별에 사용되는 핵심 식은 다음과 같습니다.
s = (x - xt)^2 + (y - yt)^2 – r*r
여기서 t(xt, yt)는 평면 위의 임의의 점이며, 세 점 (x1, y1), (x2, y2), (x3, y3)으로 결정된 원에 대한 점 t의 상대적 위치를 값 s로 나타냅니다.
- s < 0 : 점 t는 원의 내부에 있습니다.
- s > 0 : 점 t는 원의 외부에 있습니다.
- s = 0 : 점 t는 원주, 즉 원의 경계선 위에 있습니다.
원리: 원의 중심과 반지름 구하기
세 점을 모두 지나는 원(삼각형의 외접원)의 중심은, 두 점씩 이은 선분들의 수직이등분선이 만나는 교점에서 구할 수 있습니다. 프로그램에서는 먼저 두 쌍의 점에 대한 직선의 기울기 a1, a2를 계산한 뒤, 이를 이용해 원의 중심 좌표 (c1, c2)를 구하고, 중심에서 원 위의 한 점까지의 거리로 반지름 r을 산출합니다.
알고리즘
시작
세 점의 좌표를 준비합니다.
상수 L = 0과 H = 20을 선언합니다.
방정식 계산에 필요한 변수들을 선언합니다.
rand() 함수를 사용해 실행할 때마다 서로 다른 좌표값을 무작위로 생성합니다.
수직이등분선의 성질을 이용해 원의 중심(c1, c2)을 계산합니다.
중심과 원 위의 한 점 사이의 거리로 반지름 r을 계산합니다.
검사할 점을 입력받아 s 값을 계산합니다.
if s < 0 이면 "점은 원의 내부에 있습니다"를 출력합니다.
else if s > 0 이면 "점은 원의 외부에 있습니다"를 출력합니다.
else(s = 0)이면 "점은 원 위에 있습니다"를 출력합니다.
종료
예제 코드
#include<time.h>
#include<stdlib.h>
#include<iostream>
#include<math.h>
using namespace std;
const int L = 0;
const int H = 20;
int main(int argc, char **argv) {
time_t s;
time(&s);
srand((unsigned int) s);
double x1, x2, y1, y2, x3, y3;
double a1, a2, c1, c2, r;
x1 = rand() % (H - L + 1) + L;
x2 = rand() % (H - L + 1) + L;
x3 = rand() % (H - L + 1) + L;
y1 = rand() % (H - L + 1) + L;
y2 = rand() % (H - L + 1) + L;
y3 = rand() % (H - L + 1) + L;
// 두 현(chord)에 대한 직선의 기울기 계산
a1 = (y1 - y2) / (x1 - x2);
a2 = (y3 - y2) / (x3 - x2);
// 원의 중심 계산
c1 = ((a1 * a2 * (y3 - y1)) + (a1 * (x2 + x3)) - (a2 * (x1 + x2))) / (2 * (a1 - a2));
c2 = ((((x1 + x2) / 2) - c1) / (-1 * a1)) + ((y1 + y2) / 2);
// 반지름 계산
r = sqrt(((x3 - c1) * (x3 - c1)) + ((y3 - c2) * (y3 - c2)));
cout << "The points on the circle are: (" << x1 << ", " << y1 << "), ("
<< x2 << ", " << y2 << "), (" << x3 << ", " << y3 << ")";
cout << "\nThe center of the circle is (" << c1 << ", " << c2 << ") and radius is " << r;
cout << "\nEnter the point : ";
int u, v;
cin >> u;
cin >> v;
double s1 = ((u - c1) * (u - c1)) + ((v - c2) * (v - c1)) - (r * r);
if (s1 < 0)
cout << "\nThe point lies inside the circle";
else if (s1 > 0)
cout << "\nThe point lies outside the circle";
else
cout << "\nThe point lies on the circle";
return 0;
}
참고: 위 예제 코드의 s1 계산식에서 (v - c2) * (v - c1) 부분은 오타로 보입니다. 점과 중심 사이의 거리를 정확히 계산하려면 (v - c2) * (v - c2)로 수정하는 것이 바람직합니다. 아래 실행 결과는 원본 코드를 그대로 실행했을 때의 출력입니다.
실행 결과
The points on the circle are: (8, 4), (9, 17), (5, 9) The center of the circle is (12.6364, 10.8182) and radius is 7.84983 Enter the point : 7 6 The point lies outside the circle
이처럼 s 값의 부호만 확인하면 복잡한 기하학적 판단 과정 없이도, 주어진 점이 원의 내부·외부·경계 중 어디에 위치하는지 간단하게 판별할 수 있습니다.