Z = cos(theta)*V + sin(theta)*D_tick;
那么如何计算D'呢?这也很简单。首先使用叉积计算与V和D正交的向量。将其称为W:W = V×D。接下来计算与W和V正交的向量:D' = W×V = (V×D)×V。这指向正确的方向,但如果您的V和D正交,它才会成为一个单位向量。因此进行归一化处理:D' = D'/||D'||,其中||D'||是向量D'的大小。如果您有一个向量数学包,可以通过该方式执行此操作
D_tick = ((V.cross(D)).cross(V)).normalize();
一个注意点:如果||D'||为零怎么办?当且仅当Δφ是pi弧度(或180度)的倍数时才会发生这种情况。或者,当V和D平行或反向平行时也会发生这种情况。在这种特殊情况下,你的问题是不合适的。你应该检查这种特殊情况。
附录
对于三维空间中的向量,我的(V×D)×V和comingstorm的D - V*((D·V)/(V·V))是相同的。因为V是一个单位向量,他的D-V*((D·V)/(V·V))简化为D-V(D·V)。根据向量三重积恒等式(http://mathworld.wolfram.com/VectorTripleProduct.html),我的(V×D)×V等于D(V·V)-V(D·V),这又简化为D-V(D·V),因为V是一个单位向量。
D_tick
按照 length(V)
进行缩放,才能得到正确的旋转。 - comingstorm一种方法是找到与V
垂直的D
分量,将其放大到相等长度,并使用sin()
和cos()
进行向量求和:
D_perp = D - V * ((D . V)/(V . V))
D_perp_scaled = D_perp * (|V|/|D_perp|)
result = cos(theta) * V + sin(theta) * D_perp_scaled
除非D
与V
平行,否则这是明确定义的,这将导致|D_perp| == 0
并在除法中引起问题。 这并不令人惊讶:在那种情况下,您的旋转平面是不明确的-不清楚应该沿哪个方向旋转!
从数学上讲,找到垂直线的这种方法相当于其他答案中提到的叉积方法cross(cross(V,D),V)
,但可能更简单,并且适用于任何矢量空间(例如,2-D和4-D矢量,而不仅仅是3-D)。
向量Q由叉积V × D给出。两个三维向量的叉积始终垂直于叉积的两个参数。因此,这将是旋转轴。在您的情况下,Q将由以下方式给出:
<b>Q</b><sub>x</sub> = <b>V</b><sub>y</sub><b>D</b><sub>z</sub> - <b>V</b><sub>z</sub><b>D</b><sub>y</sub>
<b>Q</b><sub>y</sub> = <b>V</b><sub>z</sub><b>D</b><sub>x</sub> - <b>V</b><sub>x</sub><b>D</b><sub>z</sub>
<b>Q</b><sub>z</sub> = <b>V</b><sub>x</sub><b>D</b><sub>y</sub> - <b>V</b><sub>y</sub><b>D</b><sub>x</sub>