qt - 我如何从 Maya 复制这个 2D 相机变焦?
问题描述
我正在尝试重新创建 Mayas 捏缩放我正在做的项目,但我无法让它工作......我目前正在使用 python,但这里的语言实际上是不敬的。如果您知道如何实现这一点,请用适合您的任何语言进行解释(包括数学)。如果您可以在我当前来源的上下文中编写它;这将是惊人的。
我当前的实现看起来像这样(从资源下链接的 repo 中的 Inari.py 中的第 160 行开始):
def mousePressEvent(self, event: QtGui.QMouseEvent) -> None:
if event.button() == QtCore.Qt.RightButton:
self._lastRightMousePressPosition = event.pos()
self._initialRightMousePressHorizontalScalingFactor = self.matrix().m11()
self._initialRightMousePressVerticalScalingFactor = self.matrix().m22()
def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
# Camera panning and zooming
...
if self._lastRightMousePressPosition == None:
self._lastRightMousePressPosition = event.pos()
if bool(QtWidgets.QApplication.queryKeyboardModifiers() & QtCore.Qt.KeyboardModifier.AltModifier):
if bool((event.buttons() & QtCore.Qt.MiddleButton) or (event.buttons() & QtCore.Qt.LeftButton)):
...
elif bool(event.buttons() & QtCore.Qt.RightButton):
self.setTransformationAnchor(QtWidgets.QGraphicsView.NoAnchor)
# TODO: Make zooming slower when distanceToOrigin increases
# Capture data for correcting view translation offset.
oldSceneSpaceOriginPoint = self.mapToScene(self._lastRightMousePressPosition)
### Calculate scaleing factor
cursorPoint = np.array((self.mapToScene(event.pos()).x(), self.mapToScene(event.pos()).y()))
originPoint = np.array((self.mapToScene(self._lastRightMousePressPosition).x(), self.mapToScene(self._lastRightMousePressPosition).y()))
orientationPoint = np.add(originPoint, np.array((1, 1)))
orientationVector = np.subtract(orientationPoint, originPoint)
cursorVector = np.subtract(orientationPoint, cursorPoint)
# Introduce a small constant value if the vector length is 0.
# This is needed since the vector normalization calulation will cause an error if the vector has a length of 0
orientationVector = np.add(orientationVector, np.array((0.001, 0.001))) if bool(np.linalg.norm(orientationVector) == 0) else orientationVector
cursorVector = np.add(cursorVector, np.array((0.001, 0.001))) if bool(np.linalg.norm(cursorVector) == 0) else cursorVector
orientationUnitVector = orientationVector/np.linalg.norm(orientationVector) # Normalization calulation
cursorUnitVector = cursorVector/np.linalg.norm(cursorVector) # Normalization calulation
dotProduct = np.dot(orientationUnitVector, cursorUnitVector)
distanceToOrigin = np.linalg.norm(cursorPoint - originPoint)
globalScaleFactor = (dotProduct * distanceToOrigin * 0.01) # dot * dist * zoomSensitivity
### Create the actial matrix for applying the scale; the initial scaleing factors should be set on mouse putton pressed.
print(globalScaleFactor)
horizontalScalingFactor = self._initialRightMousePressHorizontalScalingFactor + globalScaleFactor # FIXME: This should possibly not by multiplying since it wont be linear; i think...
verticalScalingFactor = self._initialRightMousePressVerticalScalingFactor + globalScaleFactor # FIXME: If addition or subtraction is the correct way to go, the globalScaleFactor range need to change.
verticalShearingFactor = self.matrix().m12()
horizontalShearingFactor = self.matrix().m21()
self.setMatrix(QtGui.QMatrix(horizontalScalingFactor, verticalShearingFactor, horizontalShearingFactor, verticalScalingFactor, self.matrix().dx(), self.matrix().dy()))
# Correct view translation offset.
newSceneSpaceOriginPoint = self.mapToScene(self._lastRightMousePressPosition)
translationDelta = newSceneSpaceOriginPoint - oldSceneSpaceOriginPoint;
self.translate(translationDelta.x(), translationDelta.y())
...
资源:
- 想要的效果:https ://i.gyazo.com/244ca7976de59712198e6cd671c8094c.mp4
- 我目前的实现:https ://gyazo.com/34540d57f5ba74f59fe533d5bdb00334
- 我的整个源代码(如 Inari.py 中的 300 行):https ://github.com/KhaosSystems/Inari
解决方案
推荐阅读
- python-3.x - 在 df 列中的 strs 上使用 str.join
- h2o - h2o.ai AutoML StackedEnsemble 给出了错误的优越验证指标
- google-analytics - GTM 解析错误。')' 预期 _ GA + Oracle Bluekai 标记
- android - Android Studio,Kotlin:BitmapFactory.decodeStream() 返回 null
- java - 如何围绕异步代码部分包装方法
- arduino - 将数据发送到云服务器时出错,arduino 滞后
- python - 比较 pandas DataFrame 中的值
- java - Jpa 从 MySQL 数据库中获取不一致的数据
- jquery - 在网站上导航上一篇/下一篇文章的最佳方式
- windows-installer - InstallShield:如何删除 MSI 在卸载程序时不知道的文件和子文件夹?