使用矩阵在三维中旋转关于任意轴

时间:2017-07-18 07:48:14

标签: math graphics 3d

我遇到了关于交互式计算机图形学的数学问题。 我总结并抽象出这个问题如下:

我要旋转一个三维坐标 P(x 1 ,y 1 ,z 1 O(x 0 ,y 0 ,z 0

我们已经知道了2个载体 u v

u 是转化前 O 的方向。

v 是转化后 O 的方向。

我想知道如何进行计算并获得 Q

的坐标

enter image description here

非常感谢。

解决方案:

使用以下矩阵在3维中旋转关于任意轴:

旋转轴向量(标准化):( u,v,w)

旋转中心的位置坐标:(a,b,c)

旋转天使:theta

enter image description here

参考:

https://docs.google.com/viewer?a=v&pid=sites&srcid=ZGVmYXVsdGRvbWFpbnxnbGVubm11cnJheXxneDoyMTJiZTZlNzVlMjFiZTFi

4 个答案:

答案 0 :(得分:1)

通过计算# Solution number 2 by SHW: conditional statement with for loop success_true <- c() #create two vectors success_false <- c() for (log in logs) { if (log$success == TRUE) { success_true <- c(success_true, log$details) #add content of details element to the success_true vector if the condition is met } else { success_false <- c(succes_false, log$details) #add content of details element to the success_false vector if the condition is met } v之间的点积得到向量之间的角度u。执行lv(标准化)的叉积以生成旋转轴矢量u。让a成为从wu的向量O的向量。要将P转换为P,请应用以下计算轴Q和角度a的以下操作(伪代码):

l

float4 Rotate(float4 w, float l, float4 a) { float4x4 Mr = IDENTITY; quat_t quat = IDENTITY; float4 t = ZERO; float xx, yy, zz, xy, xz, yz, wx, wy, wz; quat[X] = a[X] * sin((-l / 2.0f)); quat[Y] = a[Y] * sin((-l / 2.0f)); quat[Z] = a[Z] * sin((-l / 2.0f)); quat[W] = cos((-l / 2.0f)); xx = quat[X] * quat[X]; yy = quat[Y] * quat[Y]; zz = quat[Z] * quat[Z]; xy = quat[X] * quat[Y]; xz = quat[X] * quat[Z]; yz = quat[Y] * quat[Z]; wx = quat[W] * quat[X]; wy = quat[W] * quat[Y]; wz = quat[W] * quat[Z]; Mr[0][0] = 1.0f - 2.0f * (yy + zz); Mr[0][1] = 2.0f * (xy + wz); Mr[0][2] = 2.0f * (xz - wy); Mr[0][3] = 0.0f; Mr[1][0] = 2.0f * (xy - wz); Mr[1][1] = 1.0f - 2.0f * (xx + zz); Mr[1][2] = 2.0f * (yz + wx); Mr[1][3] = 0.0f; Mr[2][0] = 2.0f * (xz + wy); Mr[2][1] = 2.0f * (yz - wx); Mr[2][2] = 1.0f - 2.0f * (xx + yy); Mr[2][3] = 0.0f; Mr[3][0] = 0.0f; Mr[3][1] = 0.0f; Mr[3][2] = 0.0f; Mr[3][3] = 1.0f; w = Mr * w; return w; } 位于旋转向量Q的末尾。伪代码中使用的算法是quaternion rotation

答案 1 :(得分:1)

只需单点就不需要轮换......所以知道的是:

$_COOKIE['name']=$_POST['name'];
after the form and at the beginning I put
if(!empty($_COOKIE['name']))
echo "Hello" . $_COOKIE['name'];

所以我们现在的距离没有改变:

u,v,O,P

和方向与|P-O| = |Q-O| 平行,所以:

u,v

但我怀疑你想构造旋转(变换矩阵),以便转换更多的点(可能是网格)。如果这是真的那么你需要至少一个已知的权利。因为有无限可能的旋转变换Q = O + v*(|P-O|/|v|) ,但每个网格的其余部分都不同...所以你需要知道至少2个非平凡点对P -> Q或旋转轴或平行平面旋转或任何其他已知数据...

无论如何,在当前状态下,您可以使用垂直于P0,P1 -> Q0,Q1的旋转轴向量和从点积获得的角度:

u,v

你只需要找出角度的符号,所以试试两个并使用resultinq axis = cross (u,v) ang = +/-acos(dot(u,v)) 所在的那个,因此Q是最大值。围绕任意轴和点使用旋转:

这也许会有所帮助:

答案 2 :(得分:0)

如果你知道 v ,P和O那么我会建议你计算| OP |应该在轮换下保存。然后将此长度乘以单位向量 - v (我假设 u v 是单位向量:如果不是 - 将它们标准化)并翻译起源于此 - | OP | v 向量。 v 前面的负号来自您问题中的说明:“v是转换后指向 O的方向”

答案 3 :(得分:0)

P Q 距离 R O 的距离相同 R = sqrt(( x1 - x0 )^ 2 +( y1 - y0 )^ 2 +( z1 - z0 )^ 2)

OQ v 共线,因此 OQ = v * R / || v ||其中|| v ||是 v 的标准 ||的 v || = sqrt( xv ^ 2 + yv ^ 2 + zv ^ 2)

所以 Q(xq,yq,zq)的坐标为:

xq = xo + xv * R / || v ||
yq = yo + yv * R / || v ||
zq = zo + zv * R / || v ||