java可以移动旋转的形状
我正在实现一个JavaSwing应用程序,它有一个用作绘图面的JPanel。曲面渲染(活动)不同的元素。每个元素都有自己的形状和用于渲染和碰撞检测的仿射变换(每个元素使用局部坐标绘制,然后使用仿射变换(如opengl)进行变换) 可以在曲面上移动和旋转元素(这是通过变换完成的)。每次应用变换时,都会使用形状和变换创建一个区域对象(用于精确的碰撞检测) 问题是当我旋转元素(45度),然后移动它10像素。当我移动它时,元素以我不想要的旋转方向移动 有什么简单的方法可以克服这个问题吗?java可以移动旋转的形状,java,swing,transform,Java,Swing,Transform,我正在实现一个JavaSwing应用程序,它有一个用作绘图面的JPanel。曲面渲染(活动)不同的元素。每个元素都有自己的形状和用于渲染和碰撞检测的仿射变换(每个元素使用局部坐标绘制,然后使用仿射变换(如opengl)进行变换) 可以在曲面上移动和旋转元素(这是通过变换完成的)。每次应用变换时,都会使用形状和变换创建一个区域对象(用于精确的碰撞检测) 问题是当我旋转元素(45度),然后移动它10像素。当我移动它时,元素以我不想要的旋转方向移动 有什么简单的方法可以克服这个问题吗? (如果我的描述
(如果我的描述不够,我将发布一些示例代码) 编辑:
颠倒应用转换的顺序。或者取消旋转对象,移动对象,然后重新旋转对象。我们真的需要查看您的代码(甚至伪代码),以便为您提供更好的答案。颠倒您应用转换的顺序。或者取消旋转对象,移动对象,然后重新旋转对象。我们真的需要查看您的代码(甚至伪代码)才能给您提供更好的答案。我修改了您的代码,提供了
元素位置
和方向
字段,您可能希望通过getter/setter公开这些字段(可能是在返回/设置点之前防御性地复制实例)。updateTransform()
只需基于元素的当前位置和方向重新构建仿射Transform
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元素。getCompositeTransform()
,它构建当前AffineTransform
并返回它(如updateTransform()
)
- 从
元素
中删除变换
字段
- 在渲染方法中,执行以下操作:
为什么?这使您可以灵活地从外部控制元素
的绘图转换。如果要构建节点图(例如元素
可以有元素
子元素),这将非常有用您将递归地呈现图形,连接变换。顺便说一句,这种方法在3D编程中非常标准。我修改了您的代码,给出了元素位置和方向字段,您可能希望通过getter/setter公开这些字段(可能是在返回/设置点之前防御性地复制实例)。updateTransform()
只需基于元素的当前位置和方向重新构建仿射Transform
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元素。getCompositeTransform()
,它构建当前AffineTransform
并返回它(如updateTransform()
)
- 从
元素
中删除变换
字段
- 在渲染方法中,执行以下操作:
为什么?这使您可以灵活地从外部控制元素
的绘图转换。如果要构建节点图(例如元素
可以有元素
子元素),这将非常有用您将递归地呈现图形,连接变换。顺便说一句,这种方法在3D编程中非常标准。用相关代码更新了我的问题。问题是我不知道变换的顺序。+1此相关检查(非交换)转换连接的顺序。用相关代码更新了我的问题。问题是我不知道转换的顺序。+1此相关检查转换连接的(非交换)顺序。使用此代码,可以使用rotate(θ,x,y)
而不是rotate(θ)围绕当前位置旋转。无论如何,这样的增量转换是令人沮丧的,您应该考虑给予<代码>元素<代码> A<代码>位置< /代码>和<代码>旋转< /COD>属性,当它们改变时,用于重新计算<代码> > AffixTebug < /代码>,或每帧/更新一次。“在大多数图形工具包(包括Java)中,转换都是按后进先出的顺序应用的。也就是说,代码中列出的最后一个转换是实际应用的第一个转换,而代码中列出的第一个转换是实际应用的最后一个转换。“@Torious如果你想发布一个带有示例的答案,我会接受这个代码,你可以使用rotate(θ,x,y)
而不是rotate(θ)围绕当前位置旋转。无论如何,这样的增量转换是令人沮丧的,您应该考虑给予<代码>元素<代码> A<代码>位置< /代码>和<代码>旋转< /COD>属性,当它们改变时,用于重新计算<代码> > AffixTebug < /代码>,或每帧/更新一次。“在大多数图形工具包(包括Java)中,转换都是按后进先出的顺序应用的。也就是说,代码中列出的最后一个转换是实际应用的第一个转换,而代码中列出的第一个转换是实际应用的最后一个转换。“@Torious如果你能用一个例子来回答问题,我会接受它的。我有孩子抚养费,但是收集是z排序的,而不是基于树的。但是
for (Element element : elements) {
AffineTransform transform = element.getCompositeTransform();
element.draw(graphics, transform);
}