对于 QGraphicsItem,绘制对象的总体转换是什么样的?

What is does the total transformation of painted objects look like for QGraphicsItem?


painter.transform() = P,
self.transform()= L,
self.sceneTransform() = S
self.parent().transform() = P1
self.parent().parent().transform() = P2(依此类推...)

当我在不设置任何变换的情况下绘制一个点时(不在 painter 上,不在任何形状上 map,在 self 上不(除了在其他中所做的控制移动、缩放和旋转的方法)。那么这个点 x 如何使用上述矩阵变量映射到它在屏幕上的最终位置?

我的目标是充分理解这一点,以便我可以做到这一点(起初,但我总是在做 QGraphicsItem 的东西);这意味着我不想 post 一个特定的问题代码(还),因为这不一定能解决我普遍缺乏理解的问题:

所以请告诉我将绘制点映射到屏幕的矩阵乘法公式,在绘制过程中不考虑任何变换。

情况是这样开始的:
我=身份
到 = 画家原点(小部件左上角)到场景中心(屏幕上)的平移。
L=I
S=我
P = 到

对象移动

Tm = 物体在场景坐标中的平移矩阵。
Tm 标准方向(+y = 向下,+x = 右)
翻译的处理方式似乎与以下操作不同,因为有一个 setPos(x,y) 函数没有相对转换,除非您反转旧的翻译并将其也乘以。 如果 T 是以下操作序列的总矩阵,则 S 将是:
S = T * Tm^-1
同样,
P = T * Tm
L=T

对象缩放

Ts = QTransform().fromScale(Sx, Sy)
找到的缩放矩阵 L *= Ts
S *= Ts
P *= Ts
结果由 self.setTransform(self.transform().scale(Sx, Sy)).

应用

对象旋转

Tr =QTransform().fromRotation(R)找到的旋转矩阵,其中+R表示顺时针。
L *= Tr
S *= Tr
P *= Tr
结果由 self.setTransform(self.transform().rotate(R)).

应用

乘法以与传统线性代数相反的顺序完成,因此请确保所有 m12(), m21(), m13(), m31(), ... 调用都已转置。

因此在没有任何额外矩阵变化的情况下用 painter.drawPoint(*x) 绘制点 x = (x,y) 将导致 x' = x T Tm.

使用它作为模型,默认绘制的选择框 b 被绘制为 *b' = b TTm**,

所以我想在绘画之前删除缩放和旋转,然后先将它们应用到 QPainterPath。根据我们的模型,这似乎应该可行:

p = self.shape()
T = self.transform()   # Local transform doesn't include translation in scene
p = T.map(p)
# b = p + pen stroke applied
painter.save()
painter.setTransform(QTransform().fromTranslation(self.pos()))
painter.strokePath(p, pen)
painter.restore()

这不起作用,但问题似乎仍然只出在我们的翻译模型上。笔路径的缩放有效。

我们忘记了。请注意,To 将随 QGraphicsView 调整大小而改变。

所以实际上 P = T ToTm = T TmToTmTo 只触及矩阵的 dx = m31(), dy = m32() 所以,我们要做的是使用 .fromTranslate(m31, m32).

而不是 .fromTranslate(self.pos()))

有效吗?

是的,行得通!