您的位置:首页 > 其它

AffineTransform入门

2015-07-19 17:59 302 查看
这里我们要用java 2-D来进行坐标空间中的变换。看到这里貌似要去复习线性代数了(呜呜)。

这里主要讲的是仿射变换的入门,我们这一次主要是要尝试用实例证明:仿射变换的顺序是不可逆的。

我们将要看到的程序实现了两种情况,一种是先平移,再旋转;另一种是先旋转,在平移。为了能更好的理解程序,首先得了解一些基本内容。

AffineTransform,即仿射变换。那么什么是仿射变换呢?几何中,一个向量空间进行一次线性变换并接上一个平移,这么一个过程就称为仿射变换或放射映射。

可以简单地表示为:y = Ax + b ,其中有下标的字母表示向量,而粗体的字母A表示一个矩阵。

如果暂时无法理解也没有关系(我也没理解 ^_^#),没关系,我们这里仅使用了它的几个特例:平移和旋转变换。

按照惯例,下面先把整个代码贴出来:

[java]
view plaincopy

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的内容。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: