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的内容。
这里主要讲的是仿射变换的入门,我们这一次主要是要尝试用实例证明:仿射变换的顺序是不可逆的。
我们将要看到的程序实现了两种情况,一种是先平移,再旋转;另一种是先旋转,在平移。为了能更好的理解程序,首先得了解一些基本内容。
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的内容。
相关文章推荐
- Linux -gdb如何显示宏定义的值
- COJ 2024 仙境传奇(五)——一个天才的觉醒 素数筛
- java事件处理机制(自定义事件)
- 【thinkphp3.2.x】thinkphp3.2.x中有关redis缓存相关的文件
- hosts 的设置将域名与iP在本地绑定
- IOS艺术字及简单的图文混排
- 贪心 Codeforces Round #135 (Div. 2) C. Color Stripe
- [LeetCode] Find Minimum in Rotated Sorted Array II
- Android中打开raw目录下的数据库文件
- 伪装隐藏Nginx,PHP版本号提升服务器安全性
- java微信上传永久素材
- Springmvc 配置json输出的几种方式
- codeforces 557D Vitaly and Cycle
- HTTP头部解释,HTTP头部详细分析,最全HTTP头部信息
- javaThread源码
- JAVA基础_Java反射
- hdu 1528 Card Game Cheater 最大匹配
- 屏蔽控制台应用程序窗口
- bootstrap 笔记01
- GCC 参数详解