轨迹球转动不正确

我正在尝试通过参考此来源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])


子衿沉夜
浏览 86回答 1
1回答

慕妹3146593

通常你的代码工作正常。根据您编写的参考资料,您的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),因为当鼠标在球体外部单击时,可能会发生奇怪的事情,而第一个代码将形状近似为双曲线表(遵循此参考),第二个代码遵循此参考。和angle值axis在我检查时计算正确。此外,旋转矢量应为normalized: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 轴的方向,但它仍然运行良好。当你执行大量旋转时,你会发现轴不是按照常识放置的,因为这些旋转,但是当你小心地使用鼠标缓慢地向上/向下移动左/右时 - 你会看到轴有已旋转,但立方体仍在按应有的方式旋转。有一个技巧可能会改变你正在旋转的东西,它被用在这里。这样旋转是在对象坐标中进行的。我粘贴了描述,但请遵循上面的详细信息。一个额外的技巧是将旋转轴从相机坐标转换为对象坐标。当相机和物体放置不同时,它很有用。例如,如果您将对象沿 Y 轴旋转 90°(“将其头部向右转”),然后用鼠标执行垂直移动,您将在相机 X 轴上旋转,但它应该变成对象在 Z 轴上的旋转(平面桶形滚动)。通过在对象坐标中转换轴,旋转将尊重用户在相机坐标 (WYSIWYG) 中的工作。为了从相机坐标转换为对象坐标,我们取 MV 矩阵的逆(来自 MVP 矩阵三元组)。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python