Easy geometry using std::complex

Правка en2, от Hikari9, 2015-12-19 11:03:20

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

  1. Vector addition: a + b

  2. Scalar multiplication: r * a

  3. Dot product: (a.conj() * b).x

  4. Cross product: (a.conj() * b).y

  5. Squared distance: norm(a — b)orabs(a — b)`

  6. Euclidean distance: sqrt(norm(a - b))

  7. Angle of elevation: arg(b - a)

  8. Slope of line (a, b): tan(arg(b - a)) or (b-a).y / (b-a).x

  9. Polar to cartesian: polar(r, theta)

  10. Cartesian to polar: point(sqrt(norm(cart)), arg(cart))

  11. Rotation about the origin: a * polar(1.0, theta)

  12. 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

Теги geometry, complex, stl

История

 
 
 
 
Правки
 
 
  Rev. Язык Кто Когда Δ Комментарий
en6 Английский Hikari9 2015-12-24 02:11:34 197 Tiny change: '\nnote: [remainder' -brbr
en5 Английский Hikari9 2015-12-23 15:28:39 697 added more useful functions
en4 Английский Hikari9 2015-12-19 19:50:20 427 Edit on drawbacks, thanks to Zlobober
en3 Английский Hikari9 2015-12-19 11:13:21 835 Minor change to note.
en2 Английский Hikari9 2015-12-19 11:03:20 596 Tiny change: 'ition:\n\n`a + b`\n\' - (published)
en1 Английский Hikari9 2015-12-19 10:47:35 2166 Initial revision (saved to drafts)