## Wednesday, September 4, 2013

### Drawing circle and calculating sinus function without trigonometry, power, or root

The formula of a circle is quite straightforward (r=sqrt(x^2+y^2)) but it's not trivial how to draw a circle or calculate the trigonometric functions without advanced math. However, an interesting finding from 1972 makes it really easy.

Minsky discovered (by a mistake) that the following loop will draw an almost perfect circle on the screen:

loop:
x = x - epsilon * y
y = y + epsilon * x # NOTE: the x is the new x value here

Turns out that epsilon in the equation is practically the rotation angle in radians, so the above loop will gradually rotate the x and y coordinates in a circle.

Calculating sinus

If we can draw this circle, we can easily estimate the sinus values: for the current angle, which is basically the sum of epsilons so far,  we have a height (y), which just needs to be normalized to the 0-1 range to get the actual sinus for the angle.

The smaller the steps (epsilon) are, the more accurate the formula will be. However, because it's not a perfect circle, it can never be a very accurate estimation. If epsilon is large, the algorithm will draw a visible ellipsis instead of a circle (slightly tilted left).

The code in JavaScript

I've used a simple canvas object to draw on, so the core logic of the drawing looks like this:

```for(var i = 0; i < steps; i++)
{
x -= y/epsilon;
y += x/epsilon;

// Draws circle.
context.fillRect(middleX+x, middleY+y, 1, 1);

var deg = i / 2 / epsilon / Math.PI * 360; // Angle in degrees.
var sinVal = y / 100; // Normalising to 0-1

// Draws sinus wave.
context.fillRect(sinX+deg, sinY+y, 1, 1);

if(i % parseInt(steps / sinMarkerCount) == 0)
{
var text = "Sin(" + parseInt(deg) + ")=" + sinVal.toFixed(2);
// Draws couple sinus values on sinus wave.
context.fillText(text, sinX+deg, sinY+y);
}
}
```

And the result is this:

To grab the full source, go here. Or have a look at the live demo here