这里我们要用java 2-D来进行坐标空间中的变换。看到这里貌似要去复习线性代数了(呜呜)。
这里主要讲的是仿射变换的入门,我们这一次主要是要尝试用实例证明:仿射变换的顺序是不可逆的。
我们将要看到的程序实现了两种情况,一种是先平移,再旋转;另一种是先旋转,在平移。为了能更好的理解程序,首先得了解一些基本内容。
AffineTransform,即仿射变换。那么什么是仿射变换呢?几何中,一个向量空间进行一次线性变换并接上一个平移,这么一个过程就称为仿射变换或放射映射。
可以简单地表示为:y = Ax + b ,其中有下标的字母表示向量,而粗体的字母A表示一个矩阵。
如果暂时无法理解也没有关系(我也没理解 ^_^#),没关系,我们这里仅使用了它的几个特例:平移和旋转变换。
按照惯例,下面先把整个代码贴出来:
import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Checkbox;
import java.awt.CheckboxGroup;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Panel;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.util.Random;
public class AffineTest extends Applet implements ItemListener{
private Rectangle2D rect;
private Checkbox rotateFirst;
private Checkbox translateFirst;
public void init()
{
setLayout(new BorderLayout());
CheckboxGroup cbg = new CheckboxGroup();
Panel p = new Panel();
rotateFirst = new Checkbox("rotate, translate", cbg, true);
rotateFirst.addItemListener(this);
p.add(rotateFirst);
translateFirst = new Checkbox("translate, rotate", cbg, false);
translateFirst.addItemListener(this);
p.add(translateFirst);
add(p, BorderLayout.SOUTH);
rect = new Rectangle2D.Float(-0.5f, -0.5f, 1.0f, 1.0f);
}
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D)g;
final AffineTransform identify = new AffineTransform();
boolean rotate = rotateFirst.getState();
Random r = new Random();
final double oneRadian = Math.toRadians(1.0);
for(double radians = 0.0; radians < 2.0*Math.PI ; radians += oneRadian)
{
g2d.setTransform(identify);
if(rotate)
{
g2d.translate(100, 100);
g2d.rotate(radians);
}
else
{
g2d.rotate(radians);
g2d.translate(100, 100);
}
g2d.scale(100, 100);
g2d.setColor(new Color(r.nextInt()));
g2d.fill(rect);
}
}
@Override
public void itemStateChanged(ItemEvent arg0) {
// TODO Auto-generated method stub
repaint();
}
}
嗯,下面我们一步一步来看程序是怎样实现的。
一开始,我们定义了一个CheckboxGroup,它可以看作是用来存储Checkbox的一个容器。然后我们又定义了两个Checkbox用来选择是先旋转呢,还是先平移呢。成员变量中还有一个Rectangle2D,用来作为变换的基准。
接下来,我们在init函数中将Checkbox定义好,然后再将CheckboxGroup填满,最后初始化了Rectangle2D的大小。
在重写paint函数的时候,我们利用AffineTransform作[0, 2pi]的旋转变换以及平移变换。我们通过Checkbox的选择来判断这两个操作的先后顺序。
程序的结果如下所示:

对比可知,仿射变换的顺序是不能随便交换的。好吧,下次学习更多的java-2D的内容。
本文介绍了Java 2D中的仿射变换入门,通过实例展示了平移和旋转两种变换,并证明了变换顺序的不可逆性。文章提供了一段代码,根据Checkbox选择实现先旋转后平移或先平移后旋转的效果,结果显示变换顺序对结果有显著影响。
1126

被折叠的 条评论
为什么被折叠?



