在matplotlib 3D plot中实现平移

goucqfw6  于 2023-10-24  发布在  其他
关注(0)|答案(2)|浏览(125)

我在tkinter中嵌入了一个3D绘图,我试图通过将鼠标事件绑定到旋转,缩放和平移来实现交互式。我通过参考他们的axes3d source code并修改elev和azim或x,y和z限制来实现旋转和缩放功能。
然而,在源代码中没有实现平移部分。

#        elif self.button_pressed == 2:
            # pan view
            # project xv, yv, zv -> xw, yw, zw
            # pan
#            pass

所以我试着自己实现它,但我不能得到它的权利。这是我有什么,如果把他们的源代码:
我遇到的问题是如何将鼠标移动的2 dx and dy值投影到3d轴的3 dxx, dyy and dzz值中。我现在所做的是错误的,尽管我不能真正找出原因。它并不总是按照我想要的方式平移,除了elev和azim的一些值,例如当elev=0和azim=0时,或者当只有一个是90的倍数时。当elev和azim都是90的非零倍数时,它不会平移或对某些轴以相反的方式平移。当它是任何其他值时,它不能正确地投影到所有的轴上,所以看起来我在向左/右/上/下平移整个图形。

elif self.button_pressed == 2:
            # get the x and y pixel coords
            if dx == 0 and dy == 0:
                return
            # how to convert dx dy -> dxx dyy dzz? this is wrong
            minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
            elev, azim = np.deg2rad(self.elev), np.deg2rad(self.azim)
            dxx = (maxx-minx) * ( (dx/w) * np.sin(azim) + (dy/h) * np.sin(elev) )
            dyy = (maxy-miny) * ( - (dx/w) * np.cos(azim) )
            dzz = (maxz-minz) * ( - (dy/h) * np.cos(elev) )
            # pan
            self.set_xlim3d(minx + dxx, maxx + dxx)
            self.set_ylim3d(miny + dyy, maxy + dyy)
            self.set_zlim3d(minz + dzz, maxz + dzz)
            self.get_proj()
            self.figure.canvas.draw_idle()

edit:最新的matplotlib源代码已经实现了平移。

ds97pgxw

ds97pgxw1#

不知何故,这工作

elif self.button_pressed == 2:
            # get the x and y pixel coords
            if dx == 0 and dy == 0:
                return
            # convert dx dy -> dxx dyy dzz
            minx, maxx, miny, maxy, minz, maxz = self.get_w_lims()
            elev, azim = np.deg2rad(self.elev), np.deg2rad(self.azim)
            dxe = (dy/h) * np.sin(elev)
            dye = - (dx/w)
            dze = - (dy/h) * np.cos(elev)
            dxx = (maxx-minx) * ( dxe * np.cos(azim) - dye * np.sin(azim) )
            dyy = (maxy-miny) * ( dye * np.cos(azim) + dxe * np.sin(azim) )
            dzz = (maxz-minz) * ( dze )
            # pan
            self.set_xlim3d(minx + dxx, maxx + dxx)
            self.set_ylim3d(miny + dyy, maxy + dyy)
            self.set_zlim3d(minz + dzz, maxz + dzz)
            self.get_proj()
            self.figure.canvas.draw_idle()

我注意到之前只有当elev或azim中的一个为0时它才能工作,所以我想也许我需要先通过elev投影,然后再通过azim投影。

2fjabf4q

2fjabf4q2#

从Matplotlib 3.7.0开始启用平移和缩放工具栏按钮,请参阅:https://matplotlib.org/stable/users/prev_whats_new/whats_new_3.7.0.html#d-plot-pan-and-zoom-buttons
如果不使用工具栏按钮,则默认情况下,鼠标左键旋转视图,鼠标中键平移,鼠标右键缩放。
这些都应该适用于您当前拥有的任何视角。

相关问题