0

I tried to implement in JavaScript rotation around point, using rotation matrix, but for some reason I got some unexpected results - instead of moving around a point, my figure was moving along a line. Here I provide completely reproducible example, which demonstrates that after rotation distance between a rotating point and the center changes. Here it is:

var alpha = 0.10146071845187077;
var cos_ = Math.cos(alpha);
var sin_ = Math.sin(alpha);
var center = [4861165.687852355,7606554.432771027];
var pointBefore = [4847712.770874163, 7610682.032298427];
var dist1, dist2, x1, y1, x2, y2, pointAfter = [];
// 1. substract + 2. rotate + 3. get back
// 1.
x1 = pointBefore[0] - center[0];
y1 = pointBefore[1] - center[1];
// 2.
x2 = cos_ * x1 - sin_ * y1;
y2 = sin_ * x1 + cos_ * y1;
// 3.
pointAfter[0] = x2 + center[0];
pointAfter[1] = y2 + center[1];
// Check distances
dist1 = Math.sqrt(Math.pow(x1, 2) + Math.pow(y1, 2));
dist2 = Math.sqrt(Math.pow(pointAfter[0] - center[0], 2) + 
        Math.pow(pointAfter[1] - center[1], 2));
console.log(JSON.stringify({dist1: dist1, dist2: dist2}));
// -> {"dist1":14071.888753138577,"dist2":14071.88875313881}

I hope, I made some errors in math, but I cannot see them.

Jacobian
  • 10,122
  • 29
  • 128
  • 221
  • What's the expected result? And as you can see, the distance before is the same as the distance after, so that warrants you actually are rotating instead of moving on a line. – Bergi Mar 03 '16 at 20:59

1 Answers1

0

Inaccuracy is due to the fact how floating point numbers are stored: Is floating point math broken?

Basically, it's impossible to store irrational numbers and high precision real numbers in the fixed space of 64bits so there will be rounding errors which become significant after many operations. Think of the number 2/3, you cannot represent it accurately no matter the precision.

A possible solution is to either calculate with whole numbers only when possible or round the results after each operation.

Community
  • 1
  • 1
highstakes
  • 1,499
  • 9
  • 14