物体旋转角度错误
The angle of rotation of the object is wrong
我正在尝试旋转 java 中的一个对象,但我发现有些地方不对劲。
当我将它旋转 180 度时,我得到的角度值为“90°”,因此为了获得 360 度的角度,我必须将其旋转两次。
怎么了?
0°,90°,180°
代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (rotate == true) {
ship.increaseDegress();
}
ship.draw(g);
}
Ship.java
public void increaseDegress() {
rotationAngle += 10;
if(rotationAngle>360) {
rotationAngle = 0;
}
}
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.setTransform(at);
g2.draw(at.createTransformedShape(this));
}
那么,让我们快速浏览一下您的代码...
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.setTransform(at);
g2.draw(at.createTransformedShape(this));
}
所以,
- 首先你创建
AffineTransform
,不错
- 你旋转变压器,也不错
- 您将变换器应用到
Graphics
上下文...好吧,这里有问题,但让我们继续
- 您将变形器应用于形状!
因此,在单次绘制过程中,您会将形状旋转 rotationAngle * 2
!所以,当角度为10°时,形状将以20°渲染,当角度为20°时,将以40°渲染!
好的,但是还有一个问题。应用于 Graphics
上下文的转换是复合的,这意味着,根据可用代码,每次调用 draw
时,Graphics
上下文都会旋转 rotationAngle
。所以如果 rotationAngle
是 10°
- 第 1 遍时,形状将旋转 20°
- 第 2 遍时,形状将旋转 30°
- 第 3 遍时,形状将旋转 40°
- ...等等...
那么,答案是什么?
每当我将 Graphics
上下文传递给其他方法时,我都会先创建一个副本,因为我不信任任何人!
Graphics gCopy = g.create();
shape.draw(gCopy);
gCopy.dispose();
这确保 Graphics
上下文的状态返回到我调用 draw
之前的状态,这将摆脱复合转换。
另一个解决方案是,不要转换 Graphics
上下文。如果你正在改变形状,那有什么意义呢?
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.draw(at.createTransformedShape(this));
}
我正在尝试旋转 java 中的一个对象,但我发现有些地方不对劲。 当我将它旋转 180 度时,我得到的角度值为“90°”,因此为了获得 360 度的角度,我必须将其旋转两次。 怎么了? 0°,90°,180°
代码:
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (rotate == true) {
ship.increaseDegress();
}
ship.draw(g);
}
Ship.java
public void increaseDegress() {
rotationAngle += 10;
if(rotationAngle>360) {
rotationAngle = 0;
}
}
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.setTransform(at);
g2.draw(at.createTransformedShape(this));
}
那么,让我们快速浏览一下您的代码...
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.setTransform(at);
g2.draw(at.createTransformedShape(this));
}
所以,
- 首先你创建
AffineTransform
,不错 - 你旋转变压器,也不错
- 您将变换器应用到
Graphics
上下文...好吧,这里有问题,但让我们继续 - 您将变形器应用于形状!
因此,在单次绘制过程中,您会将形状旋转 rotationAngle * 2
!所以,当角度为10°时,形状将以20°渲染,当角度为20°时,将以40°渲染!
好的,但是还有一个问题。应用于 Graphics
上下文的转换是复合的,这意味着,根据可用代码,每次调用 draw
时,Graphics
上下文都会旋转 rotationAngle
。所以如果 rotationAngle
是 10°
- 第 1 遍时,形状将旋转 20°
- 第 2 遍时,形状将旋转 30°
- 第 3 遍时,形状将旋转 40°
- ...等等...
那么,答案是什么?
每当我将 Graphics
上下文传递给其他方法时,我都会先创建一个副本,因为我不信任任何人!
Graphics gCopy = g.create();
shape.draw(gCopy);
gCopy.dispose();
这确保 Graphics
上下文的状态返回到我调用 draw
之前的状态,这将摆脱复合转换。
另一个解决方案是,不要转换 Graphics
上下文。如果你正在改变形状,那有什么意义呢?
public void draw(Graphics g) {
this.g = g;
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = new AffineTransform();
Rectangle rect = this.getBounds();
at.rotate(Math.toRadians(rotationAngle), rect.getX() + rect.getWidth() / 2, rect.getY() + rect.getHeight() / 2);
g2.setColor(Color.BLUE);
g2.draw(at.createTransformedShape(this));
}