어느 끝을 시작점으로, 어느 끝을 끝점으로 볼지 정해진 선분을 벡터라고 합니다. 평면 위의 벡터는 두 개의 수, 즉 가로 방향과 세로 방향의 좌표로 나타낼 수 있습니다.

점 $\simeq$ 벡터. 둘 다 단순히 수의 쌍으로 주어지므로, 이 둘을 같은 종류의 대상으로 보고 각 점에 그 점의 위치 벡터, 즉 원점에서 출발하여 그 점으로 향하는 벡터를 대응시킬 수 있습니다.
#저장 방법
벡터에 대한 모든 연산을 담당할 클래스를 만들어 봅시다. C++에서는 이를 두 가지 방법, 즉 struct와 class로 할 수 있습니다. 둘의 주된 차이는 class에서는 기본적으로 모든 필드가 *비공개(private)*라는 점입니다. 즉, 외부에서 직접 접근할 수 없습니다. 이는 대규모 프로젝트에서 누군가 실수로 무언가를 망가뜨리지 않도록 추가로 보호하기 위해 필요하지만, 올림피아드에서는 그다지 중요하지 않으므로 struct로 선언하겠습니다. 수학과 물리학에서 통용되는 표기법에 따라 이를 r이라고 부르겠습니다. 원한다면 point, pt, vec 등 원하는 대로 이름을 붙여도 됩니다.
struct r {
int x, y;
r() {}
r(int x, int y) : x(x), y(y) {}
};
같은 이름을 가진 클래스나 구조체 안의 함수 r은 객체를 초기화할 때 호출됩니다. 이를 생성자라고 부르며, 입력 인자에 따라 서로 다른 생성자를 지정할 수 있습니다. 여기서 r()는 좌표가 정해지지 않은(그 시점에 메모리에 있던 값을 가지는) 점을 반환하고, r(x, y)는 좌표가 $(x, y)$인 점을 반환합니다.
중요한 점은 좌표를 저장하는 데 정수형인 int를 선택했다는 것입니다. 입력 좌표가 모두 정수라면, 앞으로 보게 되겠지만 모든 연산 역시 정수로 수행할 수 있는 경우가 매우 많으며, 이를 통해 부동소수점 수의 여러 문제를 피할 수 있습니다.
#벡터 연산
벡터를 받아서 그것으로 무언가를 하는 함수를 작성해 봅시다. 예를 들어, 길이를 계산하는 함수입니다:
double len(r a) { return sqrt(a.x * a.x + a.y * a.y); }
// или:
double len(r a) { return hypot(a.x, a.y); }
이것은 C 언어의 접근 방식입니다. C++에서는 메서드를 정의하는 것이 더 편리합니다:
double r::len() { return hypot(x, y); }
// (альтернативно можно добавить функцию len() внутри самой структуры)
조금 더 깔끔한 구현이라는 점 외에도, 호출 문법에서도 차이가 있습니다: len(a) 또는 a.len().
#연산자
C++에서는 +, -, * 등 거의 모든 표준 연산자를 오버로딩할 수 있습니다.
앞으로 사용할 수 있도록 + 와 -를 재정의합시다:
r operator+(r a, r b) { return {a.x + b.x, a.y + b.y}; }
r operator-(r a, r b) { return {a.x - b.x, a.y - b.y}; }
cin >> x가 실제로 어떻게 동작한다고 생각하십니까? 이것 역시 연산자 >>의 오버로딩입니다. 다음과 같이 합니다:
istream& operator>>(istream &in, r &p) {
in >> p.x >> p.y;
return in;
}
ostream& operator<<(ostream &out, r &p) {
out << p.x << " " << p.y << endl;
return out;
}
#각도와 회전
벡터가 $x$축과 이루는 각을 구하려면 삼각함수의 단위원을 떠올려 $\frac{y}{x}$의 아크탄젠트를 계산하면 됩니다.
C++와 Python에는 atan2 함수가 있으며, 이 함수는 나눗셈과 아크탄젠트를 쓰는 것보다 이 작업을 조금 더 빠르고 정확하게 수행합니다:
double r::angle() {
return atan2(y, x);
}
$[-\pi, +\pi]$ 범위의 수가 라디안 단위로 반환됩니다. 도 단위로 바꾸려면 $\frac{180}{\pi}$를 곱해야 합니다.
벡터를 각 $\alpha$만큼 회전하는 것은 다음 행렬 방정식으로 나타냅니다:
$$ Rot_{\alpha}(\overline{(x, y)}) = \begin{pmatrix} \cos(\alpha) & -\sin(\alpha) \\ \sin(\alpha) & \cos(\alpha) \end{pmatrix} \begin{pmatrix} x \\ y \end{pmatrix} = \begin{pmatrix} \cos(\alpha) \cdot x - \sin(\alpha) \cdot y \\ \sin(\alpha) \cdot x + \cos(\alpha) \cdot y \end{pmatrix} $$특히 $Rot_{90^{\circ}} (\overline{(x, y)}) = \overline{(-y,x)}$입니다.