为了账号安全,请及时绑定邮箱和手机立即绑定

轨迹球转动不正确

轨迹球转动不正确

子衿沉夜 2023-03-22 11:04:29
我正在尝试通过参考此来源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 zdef 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])
查看完整描述

1 回答

?
慕妹3146593

TA贡献1820条经验 获得超9个赞

通常你的代码工作正常。根据您编写的参考资料,您的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 矩阵三元组)。


查看完整回答
反对 回复 2023-03-22
  • 1 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信