在指定点周围旋转Java 2D图形
作者:互联网
我正在尝试编写一个程序,它将绘制围绕中心点旋转的几个形状.结果应该像Spirograph.我正在尝试使用矩形测试它,但我只能让其中两个出现在窗口中.其中一个应该是它应该的位置,但是在第一次旋转之后,它将另一个方向向上抛向窗口的左上角.它应该围绕中心点旋转和绘制.这是我的一部分代码.
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;
}
}
解决方法:
请记住,翻译和旋转是复合的,也就是说,每次应用它们时,它们都会添加到当前的转换中.
您可以通过多种方式实现此目标,但首先,我们需要复制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);
因此,所有这一切都将角度值应用于每个循环上的Graphics上下文的副本.锚点设置为centerX和centerY点
好吧,看起来没问题,但如果我调整窗口大小会怎样?
好吧,不是我所期待的.出现这种情况的原因,形状的大小,锚点,旋转,平移偏移,这些都是复合产生效果(尽管很酷).
好吧,相反,我们可以简单地为每个循环创建一个新的变换,提供我们想要的确切参数,例如……
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;
它停止整数除法问题(并截断小数值)并开始产生所需的结果
比较之前和之后的简单……
标签:paintcomponent,java,graphics 来源: https://codeday.me/bug/20191008/1872947.html