It's always a hassle to define our 2D Geometry library during a contest. Is there a way to make our computational geometry lives easier in any way? Fortunately for us, there is, at least in C++, using complex numbers.
Complex numbers are of the form a + bi, where a is the real part and b imaginary. Thus, we can let a be the x-coordinate and b be the y-coordinate. Whelp, complex numbers can be represented as 2D vectors! Therefore, we can use complex numbers to define a point instead of defining the class ourselves. You can look at std::complex reference here.
#include <iostream>
#include <complex>
using namespace std;
typedef complex<double> point;
// define x, y as real(), imag()
#define x real()
#define y imag()
int main() {
point a = 2;
point b(3, 7);
cout << a << ' ' << b << endl; // (2, 0) (3, 7)
cout << a + b << endl; // (5, 7)
}
Oh goodie! We can add points as vectors without having to define operator+. Nifty. And apparently, we can overall add points, subtract points, do scalar multiplication without defining any operator. Very nifty indeed.
point a(3, 2), b(2, -7);
// vector addition and subtraction
cout << a + b << endl; // (5,-5)
cout << a - b << endl; // (1,9)
// scalar multiplication
cout << 3.0 * a << endl; // (9,6)
cout << a / 5.0 << endl; // (0.6,0.4)
What else can we do with complex numbers? Well, there's a lot that is really easy to code.
Functions using std::complex
Vector addition:
a + b
Scalar multiplication:
r * a
Dot product:
(a.conj() * b).x
Cross product:
(a.conj() * b).y
Squared distance: norm(a — b)
or
abs(a — b)`Euclidean distance:
sqrt(norm(a - b))
Angle of elevation:
arg(b - a)
Slope of line (a, b):
tan(arg(b - a))
or(b-a).y / (b-a).x
Polar to cartesian:
polar(r, theta)
Cartesian to polar:
point(sqrt(norm(cart)), arg(cart))
Rotation about the origin:
a * polar(1.0, theta)
Rotation about pivot p:
(a-p) * polar(1.0, theta) + p
note: a.conj() * b == (ax — i ay) * (bx + i by) == (ax * bx + ay * by) + i (ax * by — ay * bx) = dot + i cross