【问题标题】:Rotation of a point about the z-axis围绕 z 轴旋转一个点
【发布时间】:2012-05-22 21:07:21
【问题描述】:

我在 3D 空间中有 3 个向量。我们称它们为xaxisyaxiszaxis。这些向量以 3D 空间某处的任意 point 为中心。我有兴趣将xaxisyaxis 向量围绕zaxis 向量旋转若干度θ

对于以下值是任意且不重要的代码:

double xaxis[3], yaxis[3], zaxis[3], point[3], theta;

我将如何将xaxisyaxis 旋转zaxis theta 度数?

未来注意:这些尝试不起作用。请参阅我在 BlueRaja-DannyPflughoeft 的帮助下找到的正确解决方案的答案

我对基于矩阵的旋转的尝试:

double rx[3][3];
double ry[3][3];
double rz[3][3];
double r[3][3];

rx[0][0] = 1;
rx[0][1] = 0;
rx[0][2] = 0;

rx[1][0] = 0;
rx[1][1] = cos(theta);
rx[1][2] = sin(theta);

rx[2][0] = 0;
rx[2][1] = -1.0 * sin(theta);
rx[2][2] = cos(theta);

ry[0][0] = cos(theta);
ry[0][1] = 0;
ry[0][2] = -1.0 * sin(theta);

ry[1][0] = 0;
ry[1][1] = 1;
ry[1][2] = 0;

ry[2][0] = sin(theta);
ry[2][1] = 0;
ry[2][2] = cos(theta);
//No rotation wanted on the zaxis
rz[0][0] = cos(0);
rz[0][1] = sin(0);
rz[0][2] = 0;

rz[1][0] = -1.0 * sin(0);
rz[1][1] = cos(0);
rz[1][2] = 0;

rz[2][0] = 0;
rz[2][1] = 0;
rz[2][2] = 1;

vtkMath::Multiply3x3(rx, ry, r); //Multiplies rx by ry and stores into r
vtkMath::Multiply3x3(r, rz, r); //Multiplies r by rz and stores into r

vtkMath::Multiply3x3(r, xaxis, xaxis);//multiplies a 3x3 by a 3x1
vtkMath::Multiply3x3(r, yaxis, yaxis);//multiplies a 3x3 by a 3x1

此尝试仅在平面位于 x-y 平面时有效:

double x, y;
x = xaxis[0];
y = xaxis[1];
xaxis[0] = x * cos(theta) - y * sin(theta);
xaxis[1] = x * sin(theta) + y * cos(theta);

x = yaxis[0];
y = yaxis[1];
yaxis[0] = x * cos(theta) - y * sin(theta);
yaxis[1] = x * sin(theta) + y * cos(theta);

使用 BlueRaja-DannyPflughoeft 给出的轴角方法:

double c = cos(theta);
double s = sin(theta);
double C = 1.0 - c;

double Q[3][3];
Q[0][0] = xaxis[0] * xaxis[0] * C + c;
Q[0][1] = xaxis[1] * xaxis[0] * C + xaxis[2] * s;
Q[0][2] = xaxis[2] * xaxis[0] * C - xaxis[1] * s;

Q[1][0] = xaxis[1] * xaxis[0] * C - xaxis[2] * s;
Q[1][1] = xaxis[1] * xaxis[1] * C + c;
Q[1][2] = xaxis[2] * xaxis[1] * C + xaxis[0] * s;

Q[2][0] = xaxis[1] * xaxis[2] * C + xaxis[1] * s;
Q[2][1] = xaxis[2] * xaxis[1] * C - xaxis[0] * s;
Q[2][2] = xaxis[2] * xaxis[2] * C + c;

double x = Q[2][1] - Q[1][2], y = Q[0][2] - Q[2][0], z = Q[1][0] - Q[0][1];
double r = sqrt(x * x + y * y + z * z);

//xaxis[0] /= r;
//xaxis[1] /= r;
//xaxis[2] /= r;

xaxis[0] = x;// ?
xaxis[1] = y;
xaxis[2] = z;

【问题讨论】:

  • 如果您使用 3D 编程,请使用库和矩阵。如果没有,这属于 math.stackexchange.com。
  • 我的建议是先找到旋转算法。例如,This 可能会有所帮助。
  • 我不明白。 x、y 和 z 轴是您测量 3 个坐标的对象。您似乎将任意向量称为“xaxis”等。为什么?您的整个问题描述听起来像是您试图听起来“正确”而没有真正考虑您在做什么以及事情的含义。如果你能澄清你真正想要的,那么我怀疑解决方案会很简单,但目前它只是一团糟。
  • @Drise:所以最终你的问题是你想将一个向量围绕另一个向量旋转某个角度。这称为旋转的轴角表示,有一种简单的方法可以使用斜对称矩阵将其转换为矩阵旋转。出于某种原因,他们没有在维基百科上的倾斜对称矩阵文章中提到它,但他们确实rotation matrix 文章下有它。
  • @Drise:你应该使用struct而不是数组,所以你可以写xaxis.x而不是xaxis[0]。另外,我认为您的意思是在您编写xaxis 的任何地方都使用zaxis。 Q 的设置看起来是正确的(尽管通常在处理矩阵时,我们将行号放在第一位,然后是列号,而不是相反),但不需要下面的所有内容 - 底部- wikipedia 上该部分的一半描述了如何从旋转矩阵-> 轴角度,这与您无关。您缺少的是将旋转矩阵乘以要旋转的向量。

标签: c++ algorithm math 3d rotation


【解决方案1】:

感谢 BlueRaja - Danny Pflughoeft:

double c = cos(theta);
double s = sin(theta);
double C = 1.0 - c;

double Q[3][3];
Q[0][0] = zaxis[0] * zaxis[0] * C + c;
Q[0][1] = zaxis[1] * zaxis[0] * C + zaxis[2] * s;
Q[0][2] = zaxis[2] * zaxis[0] * C - zaxis[1] * s;

Q[1][0] = zaxis[1] * zaxis[0] * C - zaxis[2] * s;
Q[1][1] = zaxis[1] * zaxis[1] * C + c;
Q[1][2] = zaxis[2] * zaxis[1] * C + zaxis[0] * s;

Q[2][0] = zaxis[0] * zaxis[2] * C + zaxis[1] * s;
Q[2][1] = zaxis[2] * zaxis[1] * C - zaxis[0] * s;
Q[2][2] = zaxis[2] * zaxis[2] * C + c;

xaxis[0] = xaxis[0] * Q[0][0] + xaxis[0] * Q[0][1] + xaxis[0] * Q[0][2];
xaxis[1] = xaxis[1] * Q[1][0] + xaxis[1] * Q[1][1] + xaxis[1] * Q[1][2];
xaxis[2] = xaxis[2] * Q[2][0] + xaxis[2] * Q[2][1] + xaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis

yaxis[0] = yaxis[0] * Q[0][0] + yaxis[0] * Q[0][1] + yaxis[0] * Q[0][2];
yaxis[1] = yaxis[1] * Q[1][0] + yaxis[1] * Q[1][1] + yaxis[1] * Q[1][2];
yaxis[2] = yaxis[2] * Q[2][0] + yaxis[2] * Q[2][1] + yaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis

【讨论】:

    【解决方案2】:

    我看到下面的矩阵乘法是错误的!

    如上所述,它可以用xaxis[0] 分解

    xaxis[0] = xaxis[0] * Q[0][0] + xaxis[0] * Q[0][1] + xaxis[0] * Q[0][2];
    
    xaxis[0] = xaxis[0] * (Q[0][0] + Q[0][1] + Q[0][2]);
    

    这看起来不像矩阵乘法。应该是:

    xaxis1[0] = xaxis[0] * Q[0][0] + xaxis[1] * Q[0][1] + xaxis[2] * Q[0][2];
    xaxis1[1] = xaxis[0] * Q[1][0] + xaxis[1] * Q[1][1] + xaxis[2] * Q[1][2];
    xaxis1[2] = xaxis[0] * Q[2][0] + xaxis[1] * Q[2][1] + xaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis
    
    yaxis1[0] = yaxis[0] * Q[0][0] + yaxis[1] * Q[0][1] + yaxis[2] * Q[0][2];
    yaxis1[1] = yaxis[0] * Q[1][0] + yaxis[1] * Q[1][1] + yaxis[2] * Q[1][2];
    yaxis1[2] = yaxis[0] * Q[2][0] + yaxis[1] * Q[2][1] + yaxis[2] * Q[2][2]; // Multiply a 3x3 by 3x1 and store it as the new rotated axis
    

    【讨论】:

    • 我不确定这里有什么问题。自从我使用这段代码以来已经有一段时间了,但是当我上次使用它时它确实有效。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2011-08-22
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 2018-02-06
    相关资源
    最近更新 更多