物体旋转角度错误

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));

}