HumanJHawkins
HumanJHawkins

Reputation: 258

Why is Rotation of a Point Around Origin Losing Distance from Origin?

I am attempting to calculate the rotation of points in JavaScript, and am finding the values to be in the ballpark of 1% off (and always at about the correct angle, but 1% closer to the point of rotation). This is far more error than could be introduced by floating point imprecision, and too reliably in the same direction.

Below is HTML / JavaScript that demonstrates the code and issue. Output line 36 shows the result of rotating point (100,100) by 10 degrees 36 times. So, should be within about .000000001 of (100,100). But it is closer to (57,57).

When drawing the points, it is making a snail-shell pattern. I.e. a decaying orbit. Can anyone see what I am doing wrong?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Why is the rotation losing distance to origin?</title>
</head>
<body>
<script>
    let x = 100; let y = 100;
    let Cx = 0;  let Cy = 0;
    let rotation = 10 * Math.PI / 180; // 10 degrees as radians

    for(let i = 0; i <= 36; i++) {
        if (i > 33 || i < 3) { document.write(i + ": {" + x + ", " + y + "} <br />"); }
        else if (i === 33){ document.write(".<br />"); }
        else { document.write("."); }

        // Rotate 10 degrees from the last position.
        x = Math.cos(rotation) * (x - Cx) - Math.sin(rotation) * (y - Cy) + Cx;
        y = Math.sin(rotation) * (x - Cx) + Math.cos(rotation) * (y - Cy) + Cy;
    }
</script>
</body>
</html>

Thanks in advance for any help.

Upvotes: 0

Views: 100

Answers (1)

Ted Hopp
Ted Hopp

Reputation: 234795

The problem is with these two statements:

x = Math.cos(rotation) * (x - Cx) - Math.sin(rotation) * (y - Cy) + Cx;
y = Math.sin(rotation) * (x - Cx) + Math.cos(rotation) * (y - Cy) + Cy;

The first statement overwrites the value of x with the rotated value, and the rotated value is then used to compute the rotated y coordinate. Try this instead:

let x1 = Math.cos(rotation) * (x - Cx) - Math.sin(rotation) * (y - Cy) + Cx;
y = Math.sin(rotation) * (x - Cx) + Math.cos(rotation) * (y - Cy) + Cy;
x = x1;

Upvotes: 2

Related Questions