我在场景中使用gluDisk()
绘制一个平面圆盘。 gluDisk()
会使圆盘朝向正Z轴方向,但我希望它朝向我所拥有的某个任意法线。
显然,我需要使用glRotate()
来正确地使圆盘朝向,但应该如何旋转呢?我记得这可以使用四元数计算,但我似乎记不起来该怎么做了。
我在场景中使用gluDisk()
绘制一个平面圆盘。 gluDisk()
会使圆盘朝向正Z轴方向,但我希望它朝向我所拥有的某个任意法线。
显然,我需要使用glRotate()
来正确地使圆盘朝向,但应该如何旋转呢?我记得这可以使用四元数计算,但我似乎记不起来该怎么做了。
解决方案应该非常简单,不需要四元数。
从Normal1到Normal2的旋转轴必须垂直于两者,因此只需取它们的向量叉积。
旋转量可以很容易地从它们的点积中得出。这个值为|A|.|B|.cos(theta),但由于两个法线向量应该被标准化,所以它会给出cos(theta),因此只需取反余弦以获取旋转量。
所得的向量和角度是glRotate()
所需的参数-没有必要自己计算实际的旋转矩阵。
附:别忘了glRotate()
需要用角度表示,而正常的C三角函数使用弧度。
绕任意轴旋转:给定弧度角 r 和单位向量 u = ai + bj + ck 或 [a,b,c],定义:
q0 = cos(r/2)
q1 = sin(r/2) a
q2 = sin(r/2) b
q3 = sin(r/2) c
并从这些值构建旋转矩阵:
( q0^2+q1^2 - q2^2 - q3^2 | 2*(q1*q2 - q0*q3) | 2*(q1*q3 + q0*q2) )
Q =( 2*(q2*q1 + q0*q3) | (q0^2 - q1^2 + q2^2 - q3^2) | 2*(q2*q3 - q0*q1) )
( 2*(q3*q1 - q0*q2) | 2*(q3*q2 + q0*q1) | q0^2 - q1^2 - q2^2 + q3^2 )
四元数描述了绕轴的旋转。<w,x,y,z>
将围绕轴<x,y,z>
进行某些旋转,具体取决于w
和向量的大小之间的平衡。
<cos θ/2, x*sin θ/2, y*sin θ/2, z*sin θ/2>, where |<x, y, z>| = 1
<0, 1, 0>
,四元数将为<cos 90°, 0, sin 90°, 0>
=<0, 0, 1, 0>
。<x,y,z>
,需要找到旋转向量和旋转角度。要找到旋转轴,可以取当前向量与期望方向的叉积。<0, 0, 1>
。如果您想将其面对<x,y,z>
,则旋转轴将为<0, 0, 1>x<x, y, z>=<-y, x, 0>
,角度将为arctan(sqrt(x^2+y^2),z)
。四元数变成:<cos(θ/2), -y*sin(θ/2), x*sin(θ/2), 0>, where θ = arctan(sqrt(x^2+y^2), z)
glRotate
可能没问题,但我只是一般性地指出)。如果它们平行,则叉积为零向量,无法进行旋转。如果两个向量平行且方向相同,则无需进行任何操作。如果两个向量平行且方向相反,则可以围绕任何不与“Normal1”平行的轴旋转“Normal1”的2 * PI以到达“Normal2” - 但这可能会以不希望的方式旋转矩阵的其他轴(未完全考虑)。 - DisplayName