같은 다각형의 E=(12,5), F=(9,6), G=(11,10)을 선택하면 EF=(−3,1), EG=(−1,5)입니다. 외적은 (−3)×5−1×(−1)=−14이므로 E→F→G는 시계 방향입니다. F는 다각형 안쪽으로 들어간 꼭짓점입니다.
▲ [그림 2] 10각형의 E → F → G: 외적 −14, 시계 방향
변 AB 위에 K=(2,2)를 놓으면 A→K→B의 외적은 1×(−2)−(−1)×2=0입니다. 세 점이 일직선에 놓이는지는 선분의 기울기와 관계없이 외적으로 확인할 수 있습니다.
▲ [그림 3] 기울어진 변 위의 A → K → B: 외적 0
기준점 A의 좌표를 빼서 두 벡터를 만들면 A를 원점으로 옮겨 생각할 수 있습니다. 외적의 절댓값은 평행사변형의 넓이이고, 두 벡터가 놓인 순서를 바꾸면 부호가 반대가 됩니다. 이 부호로 직선의 어느 쪽에 점이 있는지를 판정합니다. 곱셈과 뺄셈으로 계산하므로 수직선에서도 기울기를 나누어 구할 필요가 없습니다.
복잡도
고정된 세 점을 기준으로 합니다.
연산
시간복잡도
공간복잡도
CCW 판별
O(1)
추가 O(1)
예제
문제
세 점을 주어진 순서대로 연결할 때의 방향을 판별하여라.
입력
첫째 줄부터 셋째 줄까지 점 A,B,C의 좌표가 순서대로 주어진다. 각 줄에는 해당 점의 x좌표와 y좌표가 공백을 사이에 두고 주어진다. 각 좌표는 0 이상 100 이하의 정수이다.
출력
반시계 방향이면 1, 일직선이면 0, 시계 방향이면 −1을 출력한다.
예제 입력
1 3
3 1
7 2
예제 출력
1
예제 코드
C++20
#include <iostream>using namespace std;struct point { int x, y;};int cross(const point& a, const point& b, const point& c) { return (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);}int main() { point a, b, c; int v; cin >> a.x >> a.y; cin >> b.x >> b.y; cin >> c.x >> c.y; v = cross(a, b, c); if (v > 0) cout << 1 << '\n'; else if (v == 0) cout << 0 << '\n'; else cout << -1 << '\n';}
Java 17
import java.util.*;public class Main { static int cross(int[] a, int[] b, int[] c) { return (b[0] - a[0]) * (c[1] - a[1]) - (b[1] - a[1]) * (c[0] - a[0]); } public static void main(String[] args) { Scanner sc; int[] a, b, c; int v; sc = new Scanner(System.in); a = new int[]{sc.nextInt(), sc.nextInt()}; b = new int[]{sc.nextInt(), sc.nextInt()}; c = new int[]{sc.nextInt(), sc.nextInt()}; v = cross(a, b, c); if (v > 0) System.out.println(1); else if (v == 0) System.out.println(0); else System.out.println(-1); }}