C ++: вращающаяся точка вокруг начала координат, но с некоторой границей точка вывода неверна - PullRequest
1 голос
/ 18 февраля 2020

впервые спрашиваю. Я хочу повернуть точку в 3d в c ++ в плоскости XY и использую следующую функцию для задачи.

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

Я получил матрицу из https://gamedevelopment.tutsplus.com/tutorials/lets-build-a-3d-graphics-engine-linear-transformations--gamedev-7716

В этом я непосредственно управляю координатами точки, следовательно this-> pos [0]

Если я вызываю другую функцию с именем rotateXYP, где я сначала вычитаю математический вектор из вращающейся точки и добавляю тот же математический вектор после поворота, я получаю требуемые результаты.

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

Мой вопрос

Почему я получаю точку (1 | 0 | 0) в качестве входа для функция rotateXY (90) следует в качестве вывода.

(6.12323e-17|1|0)

вместо

(0|1|0)

, и если я вызываю функцию rotateXYP (90, некоторая точка), я получаю правильный точка, без крошечного числа по координате х. Я подозреваю, что это как-то связано с cos и sin в следующей строке кода:

this->pos[0] = cos(radian)*x - sin(radian)*y;

Поскольку я слишком неопытен в c ++, я ищу ответы и надеюсь, что это не был плохой вопрос.

Ответы [ 2 ]

2 голосов
/ 18 февраля 2020

Ваша реализация верна. Это просто природа арифметики с плавающей точкой c. Все числа представлены в виде приближений. При переводе точки вы получите лучшее число c.

Могу добавить, что этот эффект будет происходить независимо от используемого языка программирования и аппаратного обеспечения.

0 голосов
/ 18 февраля 2020

Я решил свою проблему, добавив переменную с именем точность, которая контролирует количество десятичных разрядов, которые могут иметь двойные числа.

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