Custom Matrix
Custom Matrix

Reputation: 13

C++: Rotating point around origin, but output point is not correct by some margin

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;
};

My Question

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

Answers (2)

Custom Matrix
Custom Matrix

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

André Caceres
André Caceres

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

Related Questions