Easy geometry using std::complex
Difference between en3 and en4, changed 427 character(s)
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](http://www.cplusplus.com/reference/complex/).↵

<hr>↵

#### Defining our point class↵

We can define our point class by typing `typedef complex<double> point;` at the start of our program. To access our x- and y-coordinates, we can macro the `real()` and `imag()` functions by using `#define`. Of course, don't forget to `#include <complex>` before anything.↵

~~~~~↵
#include <iostream>↵
#include <complex>↵
using namespace std;↵

// define x, y as real(), imag()↵
typedef complex<double> point;↵
#define x real()↵
#define y imag()↵

// sample program↵
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 use `std:cout` for debugging! We can also 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.↵
<hr>↵

#### Example↵

~~~~~↵
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)↵

~~~~~↵

<hr>↵

#### Functions using std::complex↵

What else can we do with complex numbers? Well, there's a lot that is really easy to code.↵

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)` or `abs(a - b)`↵

6. Euclidean distance: `sqrt(norm(a - b))`
 or `abs(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(normabs(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`↵

_**notice**: `a.conj() * b == (ax*bx + ay*by) + i (ax*by - ay*bx) = dot(a,b) + i*cross(a,b)`_↵

### Drawbacks↵
Using std::complex is very advantageous, but it has one disadvantage: you can't use `std::cin` or `scanf`. Also, if we macro x and y, we can't use them as variables. But that's rather minor, don't you think?


EDIT: Credits to [user:Zlobober,2015-12-19] for pointing out that `std::complex` has issues with integral data types. The library will work for simple arithmetic like vector addition and such, but not for `polar` or `abs`. It will compile but there will be some errors in correctness! The tip then is to rely on the library only if you're using floating point data all throughout.

History

 
 
 
 
Revisions
 
 
  Rev. Lang. By When Δ Comment
en6 English Hikari9 2015-12-24 02:11:34 197 Tiny change: '\nnote: [remainder' -brbr
en5 English Hikari9 2015-12-23 15:28:39 697 added more useful functions
en4 English Hikari9 2015-12-19 19:50:20 427 Edit on drawbacks, thanks to Zlobober
en3 English Hikari9 2015-12-19 11:13:21 835 Minor change to note.
en2 English Hikari9 2015-12-19 11:03:20 596 Tiny change: 'ition:\n\n`a + b`\n\' - (published)
en1 English Hikari9 2015-12-19 10:47:35 2166 Initial revision (saved to drafts)