Walking Paths with Complex Numbers
dannythecoder.wordpress.com
dannythecoder.wordpress.com
(edit: added reference to geometric algebras, which are cleaner than rotation matrices for intuitively modeling this.)
If you do want to think of geometry in terms of linear algebra structures, you probably want to be studying Geometric Algebra.
My point is, I think it's harmful to say "hey, you - you're trying to solve a problem in 2d space? Have you considered using complex numbers?" When the correct thing to do is "have you considered using the algebra of N-d spaces?" (that is, Clifford/geometric algebra), and leave all the magical complex numbers out of it.
It's easy to reach for complex numbers when they're built-in. Do you have to use Maple/Mathematica for this stuff, or can you do it easily in Python/JS/&c ?
You can find the first chapter as a pdf download here: http://geometricalgebra.org/downloads/ga4cs_chapter1.pdf. It contains some code examples, and the complete source code is here: http://geometricalgebra.org/sandbox.html
The GACS book is indeed great. The “conformal model” defined there is very pleasant to work with. If you want to learn about it without buying a textbook, there’s also this PhD thesis: http://www2.eng.cam.ac.uk/~rjw57/pdf/r_wareham_pdh_thesis.pd...
Even more lightweight than matrices is just implementing the transformation on vector objects yourself: a 90-degree rotation left is R(x,y) = (-y, x), and (-R)(x,y) = -(R(x,y)). In higher dimensions this remains true for any 2-dimension subplane, so R_zx(x,y,z) = (z,y,-x).
Rotation matrices / other formulations become necessary when you're dealing with being able to rotate through any angle.
Though, doing rotations of the matrix 'y = Rx' form suffers mathematical problems like numerical instability and bad behavior. Quaternion rotations or Geometric Algebra's rotors (which are equivalent for N=3, and both take the form y = RxR^-1) work a lot better, and also eliminate a lot of the redundancy in the (skew-symmetric) rotation matrices formulation (4 variables instead of 9, for 3d).
What I mean is that the intuition around complex numbers doesn't extend. Certainly not the "i is the square root of -1"-level understanding of complex numbers.
Clifford algebras are better thought of as structures built over the higher-dimension vectors spaces, with little relationship to algebras/fields. They have much more in common with the matrix representation than the algebraic one. The algebraic perspective only supports complex, quaternion, and octonion numbers before breaking down.
>Since you need to keep track of your current orientation this slightly complicates things a bit
>If at each step we keep the imaginary multiplication term from the previous step we can effectively encode the rotation in our expression
Why, you could just keep track of the rotation as an angle, which would likewise be a result of the previous step. In binary there wouldn't even be much of a difference: Look at a 2-bit value either as a modulo 4 ring of type pi/2, or as a modulo 2 vector of the two complex components. That's my first thought, at least. Although, the real and imaginary parts would always have opposite values, so only one bit is needed. I wonder if complexity analysis would show a difference.
I recommend reading this[1] article. I found it very enlightening about why complex numbers are useful.
[1] https://acko.net/blog/how-to-fold-a-julia-fractal/
edit: Warning - [1] requires WebGL.
fixed, otherwise e^pi would be trivially wrong
IMO the best way to think of it is as the quotient or ratio between two arbitrary vectors T = v/u in a Euclidean vector space. Or equivalently, as a type of mathematical operator which you can apply (by multiplication on the left) to one vector u to produce another vector v, i.e. Tu = (v/u)u = v. This operator T will scale and rotate any other vector in the plane spanned by your two vectors u and v in the same way.
http://geocalc.clas.asu.edu/pdf/OerstedMedalLecture.pdf http://geocalc.clas.asu.edu/pdf/GrassmannsVision.pdf
def rotate(vector, angle):
rotation_matrix = [
[cos(angle), -sin(angle)],
[sin(angle), cos(angle)]
]
return rotation_matrix * vector
position = (0, 0)
velocity = (0, 1)
for instruction in [x.strip() for x in input.split(",")]:
direction = instruction[0]
distance = int(instruction[1:])
angle = 90 if direction == 'L' else -90
velocity = rotate(velocity, angle)
position += velocity * distance
print position