1. CCW 란
- CCW (Counter Clock Wise, 원래 의미는 시계 반대방향) 는 3개의 점 r, p, q가 있을때 벡터 rp를 기준으로 점 q가 어느 위치(왼쪽, 같은 직선, 오른쪽)에 있는지를 판별하는 방법입니다.
- 벡터의 외적입니다.
- 외적은 교환법칙이 성립하지 않습니다. AB 와 BA가 같지 않습니다.
- 기하 알고리즘의 가장 기본 개념입니다.
- 보통 결과물은 다음과 같이 작성합니다.
- 1) 왼쪽에 있을때, 1
- 2) 같은 직선상에 있을때, 0
- 3) 오른쪽에 있을때, -1
2. 벡터
- 2차원 평면에서 벡터는 항상 원점에서 어느 점까지의 거리입니다.
- 두 개의 점이 있고, 시작점이 원점이 아닐때는 시작점을 원점으로 맞춰 벡터를 만듭니다.
3. 외적
- CCW 입니다.
- 외적 이란 두 벡터 사이의 곱연산입니다.
- 외적의 결과물은 두 벡터가 사이에 이루는 평행 사변형의 면적과 같습니다.
- 외적은 교환법칙이 성립하지 않습니다. AB 와 BA가 같지 않습니다.
- 오른손 법칙이 성립합니다. AB가 있을때 A벡터에서 시작해서 B벡터를 감쌓았을때 엄지손가락이 향하는 부호가 외적 결과물이 향하는 방향입니다.
- 면적을 구하기 때문에 헤론의 공식을 사용하기도 합니다만. 아래 방법을 추천합니다.
- 원점에서 시작하는 두벡터 r, p 가 있을때 외적을 계산하는 방법은 다음과 같습니다.
r x p = r.x p.y - r.y p.x
4. 코딩
- 백준 온라인 저지 CCW 란 문제를 기준으로 작성하겠습니다.
#include <iostream>
#define lld long long int
using namespace std;
int ccw_result;
struct info{
lld x, y;
};
info point[4];
int ccw(info r, info p, info q){
lld first = (p.x - r.x) * (q.y - r.y);
lld second = (p.y - r.y) * (q.x - r.x);
lld result = first - second;
if(result > 0) return 1;
else if(result == 0) return 0;
else return -1;
}
int main(){
for(int i=1; i<=3; i++){
scanf("%lld %lld", &point[i].x, &point[i].y);
}
ccw_result = ccw(point[1], point[2], point[3]);
printf("%d\n", ccw_result);
}
5. 추천 문제
- CCW(즉, 벡터의 외적)은 평행사변형의 면적을 계산합니다.
- 평행사변형을 절반으로 나누면 삼각형의 면적이됩니다.
- 이를 사용해서 다각형의 면적을 구할 수 있습니다.
6. 소감
- 기하 알고리즘에 대해서, 저는 술담배는 해도 기하는 하지마라 라고 생각했습니다... 건강이 나빠지는 기분
- 가장 큰 이유는 낯설기 때문에
- 사실, 기하 알고리즘은 문제도 드물고, 레퍼런스도 드물고, 숫자도 너무 크고.. 등등
- 기하야 친구하자~
"기하야 친구하자~"
안돼요..!