【问题标题】:C++: Rotating point around origin, but output point is not correct by some marginC ++:围绕原点旋转点,但输出点在一定程度上不正确
【发布时间】:2020-02-18 11:25:10
【问题描述】:

第一次问。 我想在 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;
};

我从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, some point),我会得到正确的点,而 x 坐标上没有小数字。 我怀疑它与以下代码行中的 cos 和 sin 有关:

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

由于我对 c++ 太缺乏经验,我寻求答案并希望这不是一个坏问题。

【问题讨论】:

  • 为什么我将点 (1|0|0) 作为函数 rotateXY(90) 的输入,然后作为输出。 sin() 和 cos () 自然与 Pi 相关(甚至不是理性的),并且在数学库中近似为 Taylor series。暗示。必然是浮点数的弱点。 (What Every Programmer Should Know About Floating-Point Arithmetic) 实际上,6.12323e-17 是一个该死的小数字(接近 0)。恐怕你必须忍受它。 (我也是。6.12323e-17 看起来有点眼熟。);-)

标签: c++ 3d rotation


【解决方案1】:

您的实现是正确的。这只是浮点运算的本质。所有数字都表示为近似值。翻译该点时,您会获得更好的数值条件。

我可能会补充一点,这种效果的发生与所使用的编程语言和硬件无关。

【讨论】:

  • 最后一句话很重要——这不是可以消除的错误(一般情况下)。尽管错误的大小当然会根据实现和可变位深度而有所不同。
【解决方案2】:

我通过添加一个名为 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;
            };

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2014-12-31
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多