【问题标题】:Rotating Java 2D Graphics Around Specified Point围绕指定点旋转 Java 2D 图形
【发布时间】:2015-09-11 00:08:55
【问题描述】:

我正在尝试编写一个程序,该程序将绘制几个围绕中心点旋转的形状。结果应该类似于螺旋仪。我正在尝试使用矩形对其进行测试,但我只能让其中两个出现在窗口中。其中一个是它应该在的位置,但是在第一次旋转之后,它会在窗口的左上角向上抛出另一个正方形。它应该围绕中心点旋转和绘制。这是我的代码的一部分。

import java.awt.*;
import java.awt.geom.Ellipse2D;

import javax.swing.JPanel;

public class Shapes extends JPanel
{
private double angle;
private int type;
private int radius;
private int repeats;

public Shapes(int t, int r, int z)
{
   type = t;
   radius = r;
   repeats = z;      
   angle = 360 / repeats;
}

public void paintComponent( Graphics g )
{
  super.paintComponent( g );
  Graphics2D g2d = (Graphics2D)g;

  g.setColor(Color.red);

  int centerX = getWidth()/2;
  int centerY = getHeight()/2;

  double curAngle = 0;

  for(int i=0; i<=repeats; i+=1)
  {
      g.setColor(Color.blue);

      Rectangle tangle = new Rectangle(0, 0, radius, radius);
      g2d.rotate(Math.toRadians(curAngle));
      g2d.translate(centerX, centerY);
      g2d.draw(tangle);
      curAngle += angle;
  }

}

【问题讨论】:

  • 类似this?
  • 请注意 rotatetranslate 正在复合
  • 如果我只有 Rectangle(centerX, centerY, radius, radius);并省略翻译,奇怪的事情也会发生。
  • 您可能需要在应用下一个转换之前重置转换,基本上,每次调用 translate 时,Graphics 上下文都会再次移动该数量,因此它会逐渐移动。旋转也是如此,每次调用旋转时,都会添加到Graphics 上下文的当前旋转

标签: java graphics paintcomponent


【解决方案1】:

请记住,translaterotate 是复合的,也就是说,每次应用它们时,它们都会添加到当前转换中。

您可以通过多种方式实现此目的,但首先,我们需要复制Graphics 上下文。尤其是当您弄乱转换时,这一点很重要,您可以使用 Graphics 上下文的副本,因为这将使原始文件不受影响(并且不会影响之后可能绘制的任何内容)

Graphics2D g2d = (Graphics2D) g.create();
//...
g2d.dispose();

所以你现在对g2d 所做的任何事情都不会影响g 的状态

现在,我们可以利用变换的“复合”效果来发挥我们的优势

Rectangle tangle = new Rectangle(0, 0, radius, radius);
//g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(angle), centerX, centerY);
g2d.draw(tangle);

所以,这一切只是将angle 的值应用于每个循环上Graphics 上下文的副本。锚点设置为centerXcenterY

好吧,看起来不错,但是如果我调整窗口大小会发生什么?

好吧,这不是我所期待的。出现这种情况的原因有很多,形状的大小、锚点、旋转、平移偏移,这些都是复合产生的效果(虽然很酷)。

好的,因此,我们可以简单地为每个循环创建一个新的变换,提供我们想要的确切参数,例如...

Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.blue);

Rectangle tangle = new Rectangle(0, 0, radius, radius);
g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(curAngle));
g2d.draw(tangle);
curAngle += angle;
g2d.dispose();

这会产生...

在玩弄代码时,我注意到随着重复次数的增加,我并没有得到想要的结果。

经过同样的挖掘,我改变了

angle = 360 / repeats;

angle = 360.d / repeats;

它停止了整数除法问题(并截断十进制值)并开始产生所需的结果

一个简单的前后对比……

【讨论】:

    猜你喜欢
    • 2014-10-16
    • 2021-05-04
    • 2014-02-08
    • 2013-02-16
    • 2017-05-26
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2019-08-30
    相关资源
    最近更新 更多