围绕另一个向量旋转一个向量
我正在为 OpenGL 编写一个 3d 矢量类。如何将向量 v1 绕另一个向量 v2 旋转角度 A?
I am writing a 3d vector class for OpenGL. How do I rotate a vector v1 about another vector v2 by an angle A?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可能会发现四元数是一种更优雅、更高效的解决方案。
最近看到这个答案发生冲突后,我想我会提供一个更可靠的答案。无需理解四元数的完整数学含义即可使用的一种。我假设(给定 C++ 标签)您有一个类似
Vector3
类,具有“明显”函数,例如inner
、cross
、*= 标量运算符等...因此,在给定原始参数的情况下,
float quat[4]
保存一个表示轴和旋转角度的单位四元数(, v2, A)
。这是四元数乘法的例程。 SSE/SIMD 或许可以加速这一过程,但复杂的变换和复杂的操作可能会增加速度。在大多数场景中,照明通常由 GPU 驱动。如果您还记得复数乘法有点奇怪,那么四元数乘法就更奇怪了。复数乘法是一种交换运算:
a*b = b*a
。四元数甚至不保留此属性,即q*p != p*q
:最后,旋转 3D“向量”
v
(或者,如果您愿意,也可以将'point'v
问题已命名为v1
,表示为向量),使用四元数:float q[4]
有一点奇怪的公式:v' = q * v * 共轭(q)
。四元数具有共轭,类似于复数。这是例程:将它们放在一起。显然,您可以在适当的情况下使用
static
关键字。现代优化编译器可能会根据自己的代码生成启发式忽略inline
提示。但现在我们只关注正确性:假设某种
Vector3
类,以及以弧度表示的(A)
,我们希望四元数表示围绕轴v2
,我们希望将四元数旋转应用于v1
以获得结果:这是人们希望在 Beta 文档站点中看到的扩展内容吗? ?我不太清楚它的要求、预期的严格性等。
You may find quaternions to be a more elegant and efficient solution.
After seeing this answer bumped recently, I though I'd provide a more robust answer. One that can be used without necessarily understanding the full mathematical implications of quaternions. I'm going to assume (given the C++ tag) that you have something like a
Vector3
class with 'obvious' functions likeinner
,cross
, and*=
scalar operators, etc...Thus
float quat[4]
holds a unit quaternion that represents the axis and angle of rotation, given the original arguments(, v2, A)
.Here's a routine for quaternion multiplication. SSE/SIMD can probably speed this up, but complicated transform & lighting are typically GPU-driven in most scenarios. If you remember complex number multiplication as a little weird, quaternion multiplication is more so. Complex number multiplication is a commutative operation:
a*b = b*a
. Quaternions don't even preserve this property, i.e.,q*p != p*q
:Finally, rotating a 3D 'vector'
v
(or if you prefer, the 'point'v
that the question has namedv1
, represented as a vector), using the quaternion:float q[4]
has a somewhat strange formula:v' = q * v * conjugate(q)
. Quaternions have conjugates, similar to complex numbers. Here's the routine:Putting it all together. Obviously you can make use of the
static
keyword where appropriate. Modern optimising compilers may ignore theinline
hint depending on their own code generation heuristics. But let's just concentrate on correctness for now:Assuming some sort of
Vector3
class, and(A)
in radians, we want the quaternion representing the rotation by the angle(A)
about the axisv2
, and we want to apply that quaternion rotation tov1
for the result:Is this the sort of thing that folks would like to see expanded upon in the Beta Documentation site? I'm not altogether clear on its requirements, expected rigour, etc.
这可能有用:
This may prove useful:
使用 3D 旋转矩阵。
Use a 3D rotation matrix.
最容易理解的方法是旋转坐标轴,使向量 v2 与 Z 轴对齐,然后绕 Z 轴旋转 A,然后再旋转回来,使 Z 轴与 v2 对齐。
当您写下这三个运算的旋转矩阵时,您可能会注意到您依次应用了三个矩阵。为了达到相同的效果,您可以将三个矩阵相乘。
The easiest-to-understand way would be rotating the coordinate axis so that vector v2 aligns with the Z axis, then rotate by A around the Z axis, and rotate back so that the Z axis aligns with v2.
When you have written down the rotation matrices for the three operations, you'll probably notice that you apply three matrices after each other. To reach the same effect, you can multiply the three matrices.
我在这里找到了这个:
http://steve.hollasch.net/cgindex/math/rotvec.html
矩阵运算给出:
我编写了自己的 Matrix3 类和 Vector3Library 来实现此向量旋转。它工作得绝对完美。我用它来避免在相机视野之外绘制模型。
我想这就是“使用 3d 旋转矩阵”方法。我快速浏览了四元数,但从未使用过它们,所以坚持使用我可以理解的东西。
I found this here:
http://steve.hollasch.net/cgindex/math/rotvec.html
matrix operations gives:
I wrote my own Matrix3 class and Vector3Library that implemented this vector rotation. It works absolutely perfectly. I use it to avoid drawing models outside the field of view of the camera.
I suppose this is the "use a 3d rotation matrix" approach. I took a quick look at quaternions, but have never used them, so stuck to something I could wrap my head around.