我正在实现一个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);
...
}
}
答案 0 :(得分:2)
撤消您正在应用转换的顺序。或者取消旋转对象,移动它,然后重新旋转对象。我们真的需要看到你的代码(甚至伪代码)给你一个比这个更好的答案。
答案 1 :(得分:2)
我已经通过提供Element
position
和orientation
字段修改了您的代码,您可能希望通过getter / setter公开这些字段(可能是在防御性地复制Point
实例在返回/设置之前)。 updateTransform()
只需根据AffineTransform
的当前Element
和position
重新构建orientation
。
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()
)。transform
。Element
字段
for (Element element : elements) {
AffineTransform transform = element.getCompositeTransform();
element.draw(graphics, transform);
}
为什么呢?这使您可以灵活地在外部控制Element
的绘图变换。如果您要构建节点图(例如Element
可以有Element
子节点)并且您将递归渲染图形,连接变换,这将非常有用。顺便说一句,这种方法在3D编程中非常标准。