Reputation: 13
first time asking. I want to rotate a point in 3d in c++ in the XY Plane and am using the following function for the task.
void rotateXY(double angle){
//save the x and y and z coordinates in seperate variables
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
double radian = angle*M_PI/180;
this->pos[0] = cos(radian)*x - sin(radian)*y;
this->pos[1] = sin(radian)*x + cos(radian)*y;
this->pos[2] = 1*z;
};
I got the matrix from https://gamedevelopment.tutsplus.com/tutorials/lets-build-a-3d-graphics-engine-linear-transformations--gamedev-7716
In this I am directly manipulating the coordinates of the point, hence the this->pos[0]
If I call another function called rotateXYP where I first substract a mathematical vector from the rotating point and add the same mathematical vector to it after the rotate I get the wanted results.
void rotateXYP(double angle, eng::point originOfRotation){
this->subVec(originOfRotation);
this->rotateXY(angle);
this->addVec(originOfRotation);
};
void rotateXY(double angle){
//save x,y and z in seperate variables for manipulation
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
//convert from degrees to radians because cmath requires it
double radian = angle*M_PI/180;
//apply the values according to a rotation matrix found on the internet
this->pos[0] = cos(radian)*x - sin(radian)*y;
this->pos[1] = sin(radian)*x + cos(radian)*y;
this->pos[2] = 1*z;
};
Why am I getting with the point (1|0|0) as an input to the function rotateXY(90) the follwing as an output.
(6.12323e-17|1|0)
instead of
(0|1|0)
and if I call the function rotateXYP(90, some point), I get the correct point, without the tiny number on the x-coordinate. I suspect it has something to do with the cos and sin in the following line of code:
this->pos[0] = cos(radian)*x - sin(radian)*y;
As I am too inexperienced with c++ I seek answeres and hope that this was not a bad question.
Upvotes: 1
Views: 128
Reputation: 13
I have solved my problem by adding a variable named accuracy which controls the number of decimal places the double is allowed to have.
void rotateXY(double angle){
//Accuracy: a is the number of decimal places
int a = 2;
int acc = pow(10,a);
//save x,y and z in seperate variables for manipulation
double x = this->pos[0]; // value 1
double y = this->pos[1]; // value 0
double z = this->pos[2]; // value 0, but in the xy rotation it is not important
//convert from degrees to radians because cmath requires it
double radian = angle*M_PI/180;
//apply the values according to a rotation matrix found on the internet
this->pos[0] = round((cos(radian)*x - sin(radian)*y)*acc)/acc;
this->pos[1] = round((sin(radian)*x + cos(radian)*y)*acc)/acc;
this->pos[2] = round((1*z)*acc)/acc;
};
Upvotes: 0
Reputation: 729
Your implementation is correct. This is just the nature of floating point arithmetic. All numbers are represented as approximations. When translating the point you get a better numeric condition.
I might add that this effect will occur independent of the programming language and hardware used.
Upvotes: 2