I've been trying to create a rotational operator using the rotational matrix R (2x2 matrix).
The elements of this matrix consist of trigonometrical functions, cos and sin from the cmath library, which take the angle in radians as their argument.
Problem is, when I try to input a multiple of pi (taken as acos(1.)) close to a known value, there is a significant rounding error.
For example; cos( pi / 2 ) = cos (90 deg) should equal 0; but the value returned is 6.12323e-17. Which is very close...but not quite right (because the value for Pi is not exact).
I've tried adding a check:
1 2 3 4 5 6 7 8 9 10
double A = cos(DEG), B = sin(DEG);
if (A < -0.9999999){A = ceil(A);}
if (B < -0.9999999){B = ceil(B);}
if (A > -0.0000001 && A < 0.0000001){A = 0.;}
if (B > -0.0000001 && B < 0.0000001){B = 0.;}
if (A > 0.9999999){A = floor(A);}
if (B > 0.9999999){B = floor(B);}
cout << "A" << A << endl;
cout << "B" << B << ",\t-B" << -B << endl;
These I think should round to the nearest key value; but A still returns the value 6.12323e-17 for cos( pi / 2) after this. Surely it should fall into the middle case for A?
When doing floating point arithmetics, errors are something you have to live with. Is there really something wrong with an error of 6*10-17 ? I really doubt that..
Managed to fit a rounding method in in the end.
The reason I wanted to round it up is because I thought it might have been the cause of an error later in the function, but it's looking more like a reference mistake (a value of the order e+66 is returned where a 1 is expected).
So while 6*10-17 is pretty much 0 for this application, and should work, a matrix of
/ 0 1 \
\ -1 0 /
is a lot easier for me to process than:
/ 6.12323*10-17 1 \
\ -1 6.12323*10-17 /
EDIT: Found and fixed the problem causing the e+66 error - rounding is just to clean up the output coordinates, which should be simple enough now using the above code segment
(reason it wasn't working before was I was editing a different class to the one I was testing /facepalm)
I mistakenly thought a non-zero result would skew a different part of my code.
This rotation works for a number of polygons, but one of the classes (rectangle) has a check to ensure that it is a rectangle (dot product for each pair of consecutive sides, should = 0).
My fear was that after a rotation, because of the non-zero component it would fail the check and not acknowledge that the final result was still a rectangle. This is incorrect though, as the error is consistent for each of the sides.
In fact; including the correction would have messed up the check more than leaving it be.
Looks like it would work - but given the other features yet to be fixed I think I'll just explain where the error comes from in the comments and documentation.