C++:围绕原点旋转点,但输出点在一定程度上不正确
C++: Rotating point around origin, but output point is not correct by some margin
第一次问。
我想在 XY 平面中用 c++ 旋转 3d 中的一个点,并使用以下函数完成任务。
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;
};
得到了矩阵
在这里我直接操作点的坐标,因此 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, some point),我会得到正确的点,没有 x 坐标上的小数字。
我怀疑它与以下代码行中的 cos 和 sin 有关:
this->pos[0] = cos(radian)*x - sin(radian)*y;
由于我对 c++ 太缺乏经验,所以我寻求答案并希望这是一个不错的问题。
您的实施是正确的。这只是浮点运算的本质。所有数字都表示为近似值。翻译点时,您会获得更好的数字条件。
我可能会补充说,这种效果的发生与所使用的编程语言和硬件无关。
我通过添加一个名为 accuracy 的变量解决了我的问题,该变量控制 double 允许的小数位数。
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;
};
第一次问。 我想在 XY 平面中用 c++ 旋转 3d 中的一个点,并使用以下函数完成任务。
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;
};
得到了矩阵
在这里我直接操作点的坐标,因此 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, some point),我会得到正确的点,没有 x 坐标上的小数字。 我怀疑它与以下代码行中的 cos 和 sin 有关:
this->pos[0] = cos(radian)*x - sin(radian)*y;
由于我对 c++ 太缺乏经验,所以我寻求答案并希望这是一个不错的问题。
您的实施是正确的。这只是浮点运算的本质。所有数字都表示为近似值。翻译点时,您会获得更好的数字条件。
我可能会补充说,这种效果的发生与所使用的编程语言和硬件无关。
我通过添加一个名为 accuracy 的变量解决了我的问题,该变量控制 double 允许的小数位数。
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;
};