围绕指定点旋转 Java 个二维图形
Rotating Java 2D Graphics Around Specified Point
我正在尝试编写一个程序来绘制几个围绕中心点旋转的形状。结果应该类似于螺旋计。我正在尝试使用矩形对其进行测试,但我只能让其中两个出现在 window 中。其中一个在它应该在的位置,但是在第一次旋转之后它把另一个正方形向上抛到 window 的左上角。它应该围绕中心点旋转和绘制。这是我的部分代码。
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;
}
}
请记住,translate
和 rotate
是复合的,也就是说,每次应用它们时,它们都会添加到当前转换中。
您可以通过多种方式实现此目的,但首先,我们需要复制 Graphics
上下文。特别是在任何时候弄乱转换时,这很重要,您可以使用 Graphics
上下文的副本来执行此操作,因为这将使原始文件不受影响(并且不会影响之后可能绘制的任何内容)
Graphics2D g2d = (Graphics2D) g.create();
//...
g2d.dispose();
所以你现在对 g2d
所做的任何事情都不会影响 g
的状态
现在,我们可以利用变换的 "compounding" 效果
Rectangle tangle = new Rectangle(0, 0, radius, radius);
//g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(angle), centerX, centerY);
g2d.draw(tangle);
因此,所有这些所做的就是将 angle
的值应用于每个循环中 Graphics
上下文的副本。锚点设置为centerX
和centerY
点
好的,看起来不错,但是如果我调整 window 的大小会怎样?
好吧,不是我所期待的。出现这种情况的原因有很多,形状的大小、锚点、旋转、平移偏移,这些都是复合产生的效果(虽然很酷)。
好的,所以,相反,我们可以简单地为每个循环创建一个新的转换,提供我们想要的确切参数,例如...
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;
它停止了整数除法问题(并截断了十进制值)并开始产生所需的结果
一个简单的前后对比...
我正在尝试编写一个程序来绘制几个围绕中心点旋转的形状。结果应该类似于螺旋计。我正在尝试使用矩形对其进行测试,但我只能让其中两个出现在 window 中。其中一个在它应该在的位置,但是在第一次旋转之后它把另一个正方形向上抛到 window 的左上角。它应该围绕中心点旋转和绘制。这是我的部分代码。
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;
}
}
请记住,translate
和 rotate
是复合的,也就是说,每次应用它们时,它们都会添加到当前转换中。
您可以通过多种方式实现此目的,但首先,我们需要复制 Graphics
上下文。特别是在任何时候弄乱转换时,这很重要,您可以使用 Graphics
上下文的副本来执行此操作,因为这将使原始文件不受影响(并且不会影响之后可能绘制的任何内容)
Graphics2D g2d = (Graphics2D) g.create();
//...
g2d.dispose();
所以你现在对 g2d
所做的任何事情都不会影响 g
现在,我们可以利用变换的 "compounding" 效果
Rectangle tangle = new Rectangle(0, 0, radius, radius);
//g2d.translate(centerX, centerY);
g2d.rotate(Math.toRadians(angle), centerX, centerY);
g2d.draw(tangle);
因此,所有这些所做的就是将 angle
的值应用于每个循环中 Graphics
上下文的副本。锚点设置为centerX
和centerY
点
好的,看起来不错,但是如果我调整 window 的大小会怎样?
好吧,不是我所期待的。出现这种情况的原因有很多,形状的大小、锚点、旋转、平移偏移,这些都是复合产生的效果(虽然很酷)。
好的,所以,相反,我们可以简单地为每个循环创建一个新的转换,提供我们想要的确切参数,例如...
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;
它停止了整数除法问题(并截断了十进制值)并开始产生所需的结果
一个简单的前后对比...