这应该很容易,但我一直试图找到一个简单的解释,我可以把握。我有一个对象,我想在OpenGL中表示为一个圆锥体。该物体具有x,y,z坐标和速度矢量vx,vy和vz。锥应指向速度矢量的方向。OpenGL从速度矢量旋转
所以,我觉得我的PyOpenGL代码应该是这个样子:
glPushMatrix()
glTranslate(x, y, z)
glPushMatrix()
# do some sort of rotation here #
glutSolidCone(base, height, slices, stacks)
glPopMatrix()
glPopMatrix()
那么,是正确的(迄今为止)?我用什么来代替“#在这里做某种旋转#”?
在我的世界里,Z轴指向(0,0,1),没有任何旋转,我的锥体也是如此。
好吧,雷托Koradi的答案似乎是,我应该采取的办法,但我不知道的一些实施细则和我的代码是行不通的。
如果我理解正确,旋转矩阵应该是4x4。 Reto向我展示了如何获得3x3,所以我假定3x3应该是4x4单位矩阵的左上角。这里是我的代码:
import numpy as np
def normalize(v):
norm = np.linalg.norm(v)
if norm > 1.0e-8: # arbitrarily small
return v/norm
else:
return v
def transform(v):
bz = normalize(v)
if (abs(v[2]) < abs(v[0])) and (abs(v[2]) < abs(v[1])):
by = normalize(np.array([v[1], -v[0], 0]))
else:
by = normalize(np.array([v[2], 0, -v[0]]))
#~ by = normalize(np.array([0, v[2], -v[1]]))
bx = np.cross(by, bz)
R = np.array([[bx[0], by[0], bz[0], 0],
[bx[1], by[1], bz[1], 0],
[bx[2], by[2], bz[2], 0],
[0, 0, 0, 1]], dtype=np.float32)
return R
,这里是它被插入渲染代码的方式:
glPushMatrix()
glTranslate(x, y, z)
glPushMatrix()
v = np.array([vx, vy, vz])
glMultMatrixf(transform(v))
glutSolidCone(base, height, slices, stacks)
glPopMatrix()
glPopMatrix()
不幸的是,这是行不通的。我的测试案例锥体只是没有正确指出,我无法识别失败模式。如果没有“glutMultMatrixf(变换(V)”行,锥沿z轴对齐,符合市场预期。
它的工作。雷托Koradi正确地确定了需要旋转矩阵,以便匹配移调。的OpenGL列顺序的代码应该是这样的(优化前):
def transform(v):
bz = normalize(v)
if (abs(v[2]) < abs(v[0])) and (abs(v[2]) < abs(v[1])):
by = normalize(np.array([v[1], -v[0], 0]))
else:
by = normalize(np.array([v[2], 0, -v[0]]))
#~ by = normalize(np.array([0, v[2], -v[1]]))
bx = np.cross(by, bz)
R = np.array([[bx[0], by[0], bz[0], 0],
[bx[1], by[1], bz[1], 0],
[bx[2], by[2], bz[2], 0],
[0, 0, 0, 1]], dtype=np.float32)
return R.T
不旋转矩阵需要一个4x4矩阵(我假设我应该使用glMultMatrixf呼叫)?速度矢量为[0,0,0]时的情况如何?我需要特殊情况下的那种情况吗? – user2483736
是的,如果您使用的是固定管道,则必须将其扩展到4x4。如果您使用着色器(在Core Profile中需要),则可以将3x3矩阵传递到着色器中。 –
您在上面添加的代码看起来很合理。根据OpenGL绑定处理矩阵的方式,您可能需要按转置顺序编写元素。至少在本地接口中,OpenGL期望矩阵按列主要顺序传入。为了调试,我将从非常简单的案例开始,并查看结果矩阵中的值。例如。用一个指向'z'方向的矢量,你应该能够通过查看矩阵来判断它是否正确。 –