У меня есть трехмерный график, который я встраиваю в tkinter
, и я пытаюсь сделать его интерактивным, привязывая события мыши к вращению, масштабированию и панорамированию. Я реализовал функцию поворота и масштабирования, обратившись к их исходному коду axes3d и самостоятельно изменив пределы высоты и азимута или x, y и z соответственно.
Однако есть часть панорамирования, которая не реализовано в исходном коде. Он просто сказал:
# elif self.button_pressed == 2:
# pan view
# project xv, yv, zv -> xw, yw, zw
# pan
# pass
Итак, я попытался реализовать это сам, но не могу понять. Вот что у меня есть, если поместить в их исходный код:
Проблема, с которой я столкнулся, заключается в том, как проецировать 2 dx and dy
значения движения мыши на 3 dxx, dyy and dzz
значения трехмерных осей. То, что у меня сейчас, неправильно, хотя я не могу понять почему. Просто он не всегда панорамирует так, как я хочу, за исключением некоторых значений высоты и азима, например, когда высота = 0 и азим = 0, или когда только один из них кратен 90. Когда и высота, и азим находятся на ненулевое значение, кратное 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()