简体   繁体   English

旋转3D点的两种方式,有什么区别

[英]Two ways of rotating 3D point, What is the difference

I need to rotate a 3D point round the Y-axis 我需要绕Y轴旋转3D点

I'm no matematician so I have searched the internet and found this page https://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/3drota.htm#Y-Axis%20Rotation 我不是伴侣,所以我已经在互联网上搜索并找到了此页面:https://www.siggraph.org/education/materials/HyperGraph/modeling/mod_tran/3drota.htm#Y-Axis%20Rotation

Using this code 使用此代码

private void RotateAroundY_1()
{
    double x = 40.46;
    double y = 16.52;
    double z = 56.5;
    double b = -1* 64.77;       // rotation degree (mult with -1 to get the rotation counter clockwise

    double B = DegreeToRadian(b);   // B


    double X = x * Math.Cos(B) + z*Math.Sin(B);
    double Y = y;
    double Z = z*Math.Cos(B) - x*Math.Sin(B);

    Console.WriteLine(string.Format("X: {0} Y: {1} Z: {2}",X,Y,Z));
}
private double DegreeToRadian(double b)
{
    return (Math.PI / 180) * b;
}

I get this result 我得到这个结果

X: -33,8639291270836 
Y: 16,52 
Z: 60,6835719455922

BUT, the rotated coordinates should be (according to the 3D CAD program and its user) 但是,旋转坐标应为(根据3D CAD程序及其用户)

X: 68.38
Y: 16,52 
Z: -12.5

If I use this code 如果我使用此代码

private void RotateAroundY_2()
{
    double x = 40.46;
    double y = 16.52;
    double z = 56.5;
    double b = -1* 64.77;   // rotation degree (mult with -1 to get the rotation counter clockwise

    double curAng = Math.Atan2(z, x);
    double X = Math.Sqrt(Math.Pow(x, 2) + Math.Pow(z, 2));
    double Y = Math.Cos(DegreeToRadian(b) + curAng) * hyp;
    double Z = Math.Sin(DegreeToRadian(b) + curAng) * hyp;

    Console.WriteLine(string.Format("X: {0} Y: {1} Z: {2}",X,Y,Z));
}
private double DegreeToRadian(double b)
{
    return (Math.PI / 180) * b;
}

I get this result 我得到这个结果

X: 68,3563218478633
Y: 16,52
Z: -12,5169830003609

So I'm going to use the RotateAroundY_2, but I wish I could understand what the difference are and why I should use the second one? 因此,我将使用RotateAroundY_2,但我希望我能理解有什么区别,为什么我要使用第二个?

ELI5 (Explain Like I'm five) ELI5(像我五岁那样解释)

you got the - sign wrong it should be on the other sinus... I do not code in C# so all the code chunks are in C++ (need to port it but that shoul dbe simple enough). 您得到了-符号错误,它应该在另一个窦...我不使用C#编写代码,因此所有代码块都在C ++中 (需要移植它,但应该足够简单)。

void rotate_y(double &x,double &y,double &z,double ang)
    {
    double u=x,v=z;
    ang*=M_PI/180.0;
    x=+u*cos(ang)-v*sin(ang);
    z=+u*sin(ang)+v*cos(ang);
    }

using it like this: 像这样使用它:

double x=40.46,y=16.52,z=56.5,ang=-64.77;
mm_log->Lines->Add(AnsiString().sprintf("(%03.3f,%03.3f,%03.3f)",x,y,z));
rotate_y(x,y,z,ang);
mm_log->Lines->Add(AnsiString().sprintf("(%03.3f,%03.3f,%03.3f)",x,y,z));

results in this output: 结果如下:

(40.460,16.520,56.500)
(68.356,16.520,-12.517)

When you got the minus on the other sin then you are rotating the other way around so multiplying angle by -1 will lead to your wanted result too. 当您在另sin获得了负值时,您将以另一种方式旋转,因此将角度乘以-1也将导致您想要的结果。

void rotate_y(double &x,double &y,double &z,double ang)
    {
    double u=x,v=z;
    ang*=-M_PI/180.0;       
    x=+u*cos(ang)+v*sin(ang);
    z=-u*sin(ang)+v*cos(ang);
    }

like this: 像这样:

(40.460,16.520,56.500)
(68.356,16.520,-12.517)

You can also optimized the rotation a bit: 您还可以对旋转进行一些优化:

void rotate_y(double &x,double &y,double &z,double ang)
    {
    double u=x,v=z,c,s;
    ang*=M_PI/180.0;
    c=cos(ang);
    s=sin(ang);
    x=+u*c-v*s;
    z=+u*s+v*c;
    }

to avoid multiple sin,cos usage. 避免多次sin,cos的使用。

The other rotation code you got is very slow and inaccurate as it relays on atan2 (that has also the potential danger of getting NaN in subresults). 您获得的另一个轮换代码非常慢且不准确,因为它在atan2中继(这也有将NaN在子结果中的潜在危险)。 It simply converts your point into polar coordinates add the delta angle and convert back to cartesian. 它只是将您的点转换为极坐标,再加上增量角,然后转换回笛卡尔坐标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM