raw math

How to map a Square to a Circle

Robert Eisele

When you work with a game controller, you would expect the joystick coordinates to be circular. In reality, you get the information from two separated axis, which spans a rectangular coordinate-frame. I was thinking about how to derive a way of mapping a rectangular grid to a circular space like so (use your mouse):

Derivation

We work on a unit circle only, as any generalization is just a scaling of the resulting equation afterwards. That means that a point \((x, y)\in P\) is defined by

\[P = \{(x, y) | x, y\in [-1, 1]\}\]

The way the mapping works is to think of a a line of constant \(x\) as well as a line of constant \(y\), which gets mapped to an ellipse. That means we have a requirement to hold true, given by the ellipse equation for a constant \(x\):

\[1 = \frac{x'^2}{x^2} + \frac{x'^2}{c^2}\]

To make sure that all points along the curve at the top of the circle are hit, we need to make sure that for any \(x\in [-1, 1]\) the ellipse passes through the point

\[(x', y') = \left(\frac{x}{\sqrt{2}}, \sqrt{1-\frac{x^2}{2}}\right)\]

Plugging this point into the first equation gives us the coefficient \(c\) for the ellipse:

\[\begin{array}{rrl} & 1 & = \frac{\frac{x^2}{2}}{x^2} + \frac{1-\frac{x^2}{2}}{c^2}\\ \Leftrightarrow & \frac{c^2}{2} & = 1 - \frac{x^2}{2}\\ \Leftrightarrow & c & = \sqrt{2 -x^2} \end{array}\]

For a constant \(x\) the ellipse is thus:

\[1 = \frac{x'^2}{x^2} + \frac{y'^2}{2-x^2}\]

In the same way we can solve for a constant \(y\) and get the ellipse:

\[1 = \frac{x'^2}{2-y^2} + \frac{y'^2}{y^2}\]

By solving for \(x'^2\) we get:

\[\begin{array}{rrl} & 1 - \frac{y'^2}{2-x^2} & = \frac{x'^2}{x^2}\\ \Leftrightarrow & x'^2 & = x^2 \left(1-\frac{y'^2}{2-x^2}\right) \end{array}\]

Plugging this into the second equation results in

\[\begin{array}{rrl} & 1 & = \frac{x^2\left(1-\frac{y'^2}{2-x^2}\right)}{2-y^2} + \frac{y'^2}{y^2}\\ \Leftrightarrow & y^2(2-y^2)(2-x^2) & = x^2y^2(2-x^2-y'^2)+y'^2(2-y^2)(2-x^2)\\ \Leftrightarrow & y'^2 & = y^2\frac{(2-x^2)(2-y^2-x^2)}{(2-x^2)(2-y^2)-x^2y^2}\\ & & = y^2\frac{(2-x^2)(2-y^2-x^2)}{4-2x^2-2y^2}\\ & & = y^2\left(1-\frac{x^2}{2}\right)\\ \Leftrightarrow & y' & = y\sqrt{1-\frac{x^2}{2}} \end{array}\]

Using symmetry, we get the mapping from a square in the interval -1 to 1, for both x and y coordinates to a unit circle. As said before, solving for the general case is simply normalizing to a square in the right size and scaling the result afterwards again.

\[(x', y') = \left(x\sqrt{1-\frac{y^2}{2}}, y\sqrt{1-\frac{x^2}{2}}\right)\]

A JavaScript function that maps a point to a unit circle can be implemented like this:

function map(x, y) {
    return [
        x * Math.sqrt(1 - y * y / 2), 
        y * Math.sqrt(1 - x * x / 2)];
}