java移动旋转的形状

我正在实现一个java swing应用程序,它有一个JPanel作为绘图表面。 表面渲染(活动)不同的元素。 每个元素都有自己的形状和仿射变换,用于渲染和碰撞检测(每个元素用局部坐标绘制,然后用仿射变换转换 – 如opengl)。

可以在表面上移动和旋转元素(这通过变换完成)。 每次应用变换时,都会使用形状和变换创建Area对象(用于准确的碰撞检测)。

问题是当我旋转元素(45度)然后移动10像素。 当我移动它时,元素沿着我不想要的旋转方向移动。

有什么简单的方法可以解决这个问题吗?
(如果我的描述不够,我会发布一些示例代码)。

编辑:

class Element { private AffineTransform transform = new AffineTransform(); private Shape shape = new Rectangle(0,0,100,100); private Area boundingBox; public void onMouseDrag(MouseEvent e) { translate(dx,dy); // dx,dy are calculated from event } public void onMouseMove(MouseEvent e) { rotate(Math.atan2(dx/dy); // dx,dy are calculated from event } public void translate(int dx,int dy) { transform.translate(dx,dy); boundingBox = new Area(shape); boundingBox.transform(transform); } public void rotate(double angle) { transform.rotate(Math.toRadians(angle)); boundingBox = new Area(shape); boundingBox.transform(transform); } public void draw(Graphics2D g2d) { g2d.setTransform(transform); g2d.draw(shape); ... } } 

我通过给出Element positionorientation字段来修改你的代码,你可能希望通过getter / setter公开它们(可能在返回/设置之前防御性地复制Point实例)。 updateTransform()只是根据Element的当前positionorientation重新构建AffineTransform

 public class Element { private Point position = new Point(); private float orientation; private AffineTransform transform = new AffineTransform(); private Shape shape = new Rectangle(0, 0, 100, 100); private Area boundingBox; public void onMouseDrag(MouseEvent e) { translate(dx, dy); } public void onMouseMove(MouseEvent e) { rotate(Math.atan2(dx / dy)); } public void translate(int dx, int dy) { position.translate(dx, dy); updateTransform(); } public void rotate(double angle) { orientation += Math.toRadians(angle); updateTransform(); } private void updateTransform() { transform.setToIdentity(); transform.translate(position.x, position.y); transform.rotate(orientation); // ... update bounding box here ... } public void draw(Graphics2D g2d) { g2d.setTransform(transform); g2d.draw(shape); } } 

另外,请考虑以下方法:

  • 更改draw(Graphics2D)draw(Graphics2D, AffineTransform transform)
  • 创建AffineTransform Element.getCompositeTransform() ,它构建当前的AffineTransform并返回它(如updateTransform() )。
  • Element删除transform字段。
  • 在您的渲染方法中,执行以下操作:

 for (Element element : elements) { AffineTransform transform = element.getCompositeTransform(); element.draw(graphics, transform); } 

为什么? 这使您可以灵活地在外部控制Element的绘图变换。 如果您要构建节点图(例如,当Element可以具有ElementElement )并且您将递归渲染图形,连接变换时,这非常有用。 顺便说一句,这种方法在3D编程中几乎是标准的。

反转您应用转换的顺序。 或者取消旋转对象,移动它,然后重新旋转对象。 我们真的需要看到你的代码(甚至伪代码)给你一个比这个更好的答案。