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:
And the result is this:
To grab the full source, go here. Or have a look at the live demo here.
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 rad = i / epsilon; // Angle in radians. 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.
Comments
Post a Comment