我正在尝试测试与 Rectangle2D.Float 和 Point2D.Float 的碰撞。我有一个包含相机的 2D 世界(它根据相机的 AffineTransform 转换图形2D Canvas )。然后,我有一个包含子对象 Y 的对象 X 的列表。 Canvas 在相机变换到 X 的仿射变换之上进行变换,因此该对象被渲染在正确的位置。我可以成功测试与对象 X 内的鼠标的碰撞,但我在测试子对象 Y 时遇到问题,因为 Y 对象“认为”它们位于位置 (0,0),即使它们已位于其他位置,因为他们的父对象 X 被重新定位为 (200,200)。换句话说,对象 X 和 Y 出现在位置 (200,200),但碰撞发生在 (0,0),而不是像预期的那样发生在 (200,200)。
我相信这与调用 AffineTransform.transform 和 AffineTransform.inverseTransform 的正确组合有关,但我无法理解正确的组合。
最佳答案
这是对交互式图形使用串联转换时出现的标准问题。
假设T
是定位对象X
的仿射变换矩阵。还令 U
为相对于 X
定位某个子对象 Y
的矩阵。然后Y
中的每个点p
都用矩阵表达式进行变换
p' = T U p
其中p'
是变换点。 p'
所在的坐标空间与鼠标坐标相同。当您在 c'
点收到鼠标点击时(我在这里使用素数 '
来匹配同一坐标中的 p'
),你有一个选择。您可以使用 (T U)^(-1)
“向后”变换 c'
以获取子对象坐标空间中的 c
。或者您可以手动计算所有点 p
的 p'
,以便将其与 c'
进行比较。
一般来说,您会想要做后者。 Java 将类似于:
AffineTransform TU = new AffineTransform(T);
TU.concatenate(U);
Point2D pPrime = new Point2D();
TU.transform(p, pPrime);
现在您很快就会注意到,由于您是手动计算这些点,因此您可能会保留转换后的点的数据结构,以便您始终可以与鼠标坐标进行比较。相同的数据结构可用于绘制屏幕,而无需任何转换:它们已经被应用。这是交互式图形的一种非常标准的技术。当整个绘图快速更新时,它就失去了吸引力。但是,当绘图很大并且一次最多更新一小部分时,这可能是性能的巨大胜利。您提供一些内存并恢复一些速度。
关于java - Java2D API 中的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11661035/