我正在尝试通过引用此来源来实现轨迹球 https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball和 https://www.khronos.org/opengl/wiki/Object_Mouse_Trackball
但是得到旋转轴后好像没有正确转动
这是我的代码片段
def compute_z(x, y):
# compute z from sphere model
# sphere size = 1
z = math.sqrt(abs(1 - math.pow(x,2) - math.pow(y,2)))
return z
def get_rotation_axis(vect_1, vect_2):
# determine rotation direction
axis = np.cross(vect_1, vect_2)
return axis
这是主要的
while True:
mouse_pos = pygame.mouse.get_pos()
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
if event.type == pygame.MOUSEMOTION:
if arcball_on:
cur_mx = mouse_pos[0]
cur_my = mouse_pos[1]
last_conv = convert_range(last_mx, last_my)
cur_conv = convert_range(cur_mx, cur_my)
a = (last_conv[0], last_conv[1], compute_z(last_conv[0], last_conv[1]))
b = (cur_conv[0], cur_conv[1], compute_z(cur_conv[0], cur_conv[1]))
angle = compute_angle(a, b)
axis = get_rotation_axis(a, b)
print(axis)
glRotatef(angle, axis[0], axis[1], -axis[2])
最佳答案
通常您的代码工作正常。根据您编写的引用资料,您的 compute_z
函数可能如下所示:
def compute_z(x, y):
# compute z from sphere model
op_squared = x ** 2 + y ** 2
r_squared = SPHERE_R ** 2
if op_squared > r_squared / 2:
z = r_squared / 2 / math.sqrt (op_squared)
else:
z = math.sqrt(r_squared - op_squared)
return z
或者更简单:
def compute_z(x, y):
# compute z from sphere model
op_squared = x ** 2 + y ** 2
r_squared = SPHERE_R ** 2
if op_squared > r_squared:
return 0
else:
return math.sqrt(r_squared - op_squared)
其中 SPHERE_R
是假设球体的半径(默认为 1),因为当鼠标在球体外部单击时,可能会发生奇怪的事情,而第一个代码将形状近似为 双曲线表(在 this reference 之后)和第二个在 this reference 之后.
angle
和 axis
值在我检查时计算正确。
此外,旋转向量应该归一化
:
def normalize(x):
x = np.asarray(x)
if np.linalg.norm(x):
return x / np.linalg.norm(x)
else:
return x
# .....
a = (last_conv[0], last_conv[1], compute_z(last_conv[0], last_conv[1]))
b = (cur_conv[0], cur_conv[1], compute_z(cur_conv[0], cur_conv[1]))
a = normalize(a)
b = normalize(b)
axis = get_rotation_axis(a, b)
axis = normalize(axis)
glRotatef
函数运行正常(您也可以更改 x 轴的方向,但它仍然运行良好。
当你执行大量旋转时,你会发现轴不是按照常识放置的,因为这些旋转,但是当你小心地使用鼠标缓慢地向上/向下移动左/右时 - 你会看到该轴已旋转,但立方体仍在按应有的方式旋转。
有一个技巧可能会改变你正在旋转的东西,它被使用了 here .这样旋转是在对象坐标中进行的。我粘贴了描述,但请遵循上面的详细信息。
An extra trick is converting the rotation axis from camera coordinates to object coordinates. It's useful when the camera and object are placed differently. For instance, if you rotate the object by 90° on the Y axis ("turn its head" to the right), then perform a vertical move with your mouse, you make a rotation on the camera X axis, but it should become a rotation on the Z axis (plane barrel roll) for the object. By converting the axis in object coordinates, the rotation will respect that the user work in camera coordinates (WYSIWYG). To transform from camera to object coordinates, we take the inverse of the MV matrix (from the MVP matrix triplet).
关于python - 轨迹球转动不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62996720/