Cartesian -> Polar Coordinates

How can you convert a vector \( (x,y) \) written in regular old rectangular, aka Cartesian, coordinates to a vector written in polar coordinates \( (r, \theta) \)? The first thing you do is draw a tiny little circle with an itsy bitsy little triangle inside of it. The diagram is so small that you probably need a magnifying glass and a very fine drawing tool. No one can know that you don't remember your high school trigonometry! It's a perfect time to close the door and do some Khan Academy.

Calculating \( r \) is pretty straight forward. You just need to calculate the length of the vector which is \( \sqrt{x^2 + y^2} \). How do you go about calculating \( \theta \)?

Using the inverse trigonometric seems like a good idea. Their domains are the ratio of sides of right triangles, and their ranges are angles, which is what we want. Upon quick inspection it becomes clear that neither \(arcsin\), \(arccos\), nor \(arctan\) are going to be able to do the whole job on their own. For example, if you use \(arcsin\), then you make the calculation: \( arcsin(\frac{y}{\sqrt{x^2+y^2}}) \). If you reflect the vector over the y-axis, thus making \( x \) negative, you'll get the same angle from \( arcsin \) as you would from the original vector. A similar thing happens if you use \( arccos \). If you use \( atan \), then you are doing this calculation: \( atan(\frac{y}{x}) \) and you can deal with reflecting across the x-axis or the y-axis, but not when you reflect over both.

Looks like there's no choice but to write our own function. It should do something like this:

  • 1st Quadrant: \( x > 0 \) and \( y > 0 \). No problem use \( atan(x,y) \).
  • 4th Quadrant: \( x > 0 \) and \( y < 0 \). Use \( atan(x, y) \). It so happens that implementations of atan do the right thing on the 1st and 4th quadrants.
  • 2nd Quadrant: \( x < 0 \) and \( y > 0 \). Reflect the vector back to the 1st Quadrant by taking \( -x \) and calculate the correct offset, \( \pi - atan(-x,y) \).
  • 3rd Quadrant: \( x < 0 \) and \( y < 0 \). Reflect the vector back to 1st Quadrant, calculate \( atan \) and add the proper offset: \( \pi + \pi/2 - atan(-x,-y) \).

There are still some edge cases left.

  • If \( 0 = x = y \) then return undefined.
  • If \( x = 0 \) and \( y > 0 \) then return \( \pi/2 \).
  • If \( x = 0 \) and \( y < 0 \) then return \( -\pi/2 \).
  • If \( y = 0 \) and \(x > 0 \) then return \( 0 \).
  • If \( y = 0 \) and \(x < 0 \) then return \( \pi \).

Guess what? This function is implemented in most languages as atan2. It is often available as a core feature or in the math library.

It is also interesting to highlight a piece of the Wikipedia article. All of the derivatives of atan2 are rational functions which means that it can be relatively easy to implement a fast program to compute it using Taylor Series.

Boids

This came up when Joe Wilner and I were working on a ClojureScript and HTML5 Canvas implementation of Boids. Check it out here! Our boids started out as squares but we wanted to draw their direction too. All of our vectors, including the acceleration vector, were in Cartesian coordinates, so we needed to figure out a way of calculating the direction of the acceleration vector. We fumbled around a bit and then Joe found atan2 which I thought was pretty damn useful and cool.