我正在尝试测试与Rectangle2D.Float和Point2D.Float的碰撞。我有一个包含相机的2D世界(它根据相机的AffineTransform转换graphics2D画布)。然后我有一个包含子对象Y的对象列表。画布在摄像机转换到X的AffineTransformation的顶部转换,因此对象在正确的位置渲染。我可以成功测试对象X内的鼠标碰撞,但是我遇到了测试子对象Y的问题,因为Y对象“认为”它们位于(0,0)位置,即使它们位于其他位置因为他们的父对象X被重新定位说(200,200)。换句话说,对象X和Y显示在位置(200,200),但是碰撞发生在(0,0)而不是(200,200),就像它应该的那样。
我认为它与调用AffineTransform.transform和AffineTransform.inverseTransform的正确组合有关,但我无法将我的大脑包裹在正确的组合中。
答案 0 :(得分:2)
这是使用串联转换进行交互式图形时出现的标准问题。
假设T
是定位对象X
的仿射变换矩阵。同样,让U
成为相对于Y
定位某个子对象X
的矩阵。然后,使用矩阵表达式
p
中的每个点Y
p' = T U p
其中p'
是转换点。 p'
所在的坐标空间与鼠标坐标相同。当您在点c'
处收到鼠标点击时(我在此处使用'
处的p'
匹配相同坐标中的c'
),您可以选择。您可以使用(T U)^(-1)
向后转换c
,以在子对象的坐标空间中获取p'
。或者,您可以为所有点p
手动计算c'
,以便将其与AffineTransform TU = new AffineTransform(T);
TU.concatenate(U);
Point2D pPrime = new Point2D();
TU.transform(p, pPrime);
进行比较。
一般来说,你会想做后者。 Java将类似于:
{{1}}
现在您将很快注意到,由于您手动计算这些点,您可能会保留变换点的数据结构,因此您始终可以与鼠标坐标进行比较。可以使用相同的数据结构来绘制屏幕而不进行任何转换:它们已经被应用。这是交互式图形的一种非常标准的技术。当整个绘图快速更新时,它就会失去吸引力。但是当绘图很大并且最多只能一次更新小块时,它可能是性能的一大胜利。你给了一些记忆并恢复了一些速度。
答案 1 :(得分:1)
如此example所示,有几件事可能有所帮助:
区分转换图形上下文和转换Shape
。
转换不是可交换的;它们是连接,就像应用于明显的最后指定的第一次应用顺序一样。
AffineTransform
包含允许锚点点的静态工厂。