Java AffineTransform入门

本文介绍了Java 2D中的仿射变换入门,通过实例展示了平移和旋转两种变换,并证明了变换顺序的不可逆性。文章提供了一段代码,根据Checkbox选择实现先旋转后平移或先平移后旋转的效果,结果显示变换顺序对结果有显著影响。

这里我们要用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的内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值