国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

香港云服务器
服務器之家 - 編程語言 - JAVA教程 - 初步解析Java中AffineTransform類的使用

初步解析Java中AffineTransform類的使用

2020-01-10 16:16computingbear JAVA教程

這篇文章主要介紹了Java中AffineTransform類的使用,AffineTransform類經常被用來處理圖片,需要的朋友可以參考下

AffineTransform類描述了一種二維仿射變換的功能,它是一種二維坐標到二維坐標之間的線性變換,保持二維圖形的“平直性”(譯注:straightness,即變換后直線還是直線不會打彎,圓弧還是圓?。┖?ldquo;平行性”(譯注:parallelness,其實是指保二維圖形間的相對位置關系不變,平行線還是平行線,相交直線的交角不變。大二學過的復變,“保形變換/保角變換”都還記得吧,數學就是王道?。。?。仿射變換可以通過一系列的原子變換的復合來實現,包括:平移(Translation)、縮放(Scale)、翻轉(Flip)、旋轉(Rotation)和剪切(Shear)。

此類變換可以用一個3×3的矩陣來表示,其最后一行為(0, 0, 1)。該變換矩陣將原坐標(x, y)變換為新坐標(x', y'),這里原坐標和新坐標皆視為最末一行為(1)的三維列向量,原列向量左乘變換矩陣得到新的列向量:

?
1
2
3
[x'] [m00 m01 m02] [x] [m00*x+m01*y+m02]
[y'] = [m10 m11 m12] [y] = [m10*x+m11*y+m12]
[1 ] [ 0 0 1 ] [1] [ 1 ]

 


幾種典型的仿射變換:

?
1
public static AffineTransform getTranslateInstance(double tx, double ty)

 

平移變換,將每一點移動到(x+tx, y+ty),變換矩陣為:

?
1
2
3
[ 1 0 tx ]
[ 0 1 ty ]
[ 0 0 1 ]


(譯注:平移變換是一種“剛體變換”,rigid-body transformation,中學學過的物理,都知道啥叫“剛體”吧,就是不會產生形變的理想物體,平移當然不會改變二維圖形的形狀。同理,下面的“旋轉變換”也是剛體變換,而“縮放”、“錯切”都是會改變圖形形狀的。)

?
1
public static AffineTransform getScaleInstance(double sx, double sy)

 

縮放變換,將每一點的橫坐標放大(縮?。┲羢x倍,縱坐標放大(縮?。┲羢y倍,變換矩陣為:

?
1
2
3
[ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 1 ]
?
1
public static AffineTransform getShearInstance(double shx, double shy)

 

剪切變換,變換矩陣為:

?
1
2
3
[ 1 shx 0 ]
[ shy 1 0 ]
[ 0 0 1 ]

相當于一個橫向剪切與一個縱向剪切的復合

?
1
2
3
[ 1 0 0 ][ 1 shx 0 ]
[ shy 1 0 ][ 0 1 0 ]
[ 0 0 1 ][ 0 0 1 ]


(譯注:“剪切變換”又稱“錯切變換”,指的是類似于四邊形不穩定性那種性質,街邊小商店那種鐵拉門都見過吧?想象一下上面鐵條構成的菱形拉動的過程,那就是“錯切”的過程。)

?
1
public static AffineTransform getRotateInstance(double theta)

 

旋轉變換,目標圖形圍繞原點順時針旋轉theta弧度,變換矩陣為:

?
1
2
3
4
[ cos(theta) -sin(theta) 0 ]
 
[ sin(theta) cos(theta) 0 ]
[ 0 0 1 ]

 

?
1
public static AffineTransform getRotateInstance(double theta, double x, double y)

 

旋轉變換,目標圖形以(x, y)為軸心順時針旋轉theta弧度,變換矩陣為:

?
1
2
3
[ cos(theta) -sin(theta) x-x*cos+y*sin]
[ sin(theta) cos(theta) y-x*sin-y*cos ]
[ 0 0 1 ]


相當于兩次平移變換與一次原點旋轉變換的復合:

?
1
2
3
[1 0 -x][cos(theta) -sin(theta) 0][1 0 x]
[0 1 -y][sin(theta) cos(theta) 0][0 1 y]
[0 0 1 ][ 0 0 1 ][0 0 1]

幾何中,一個向量空間進行一次線性變換并接上一個平移,這么一個過程就稱為仿射變換或放射映射。

可以簡單地表示為:y = Ax + b ,其中有下標的字母表示向量,而粗體的字母A表示一個矩陣。

如果暫時無法理解也沒有關系(我也沒理解 ^_^#),沒關系,我們這里僅使用了它的幾個特例:平移和旋轉變換。

按照慣例,下面先把整個代碼貼出來:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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();
 }
 
}
 
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();
 }
 
}

初步解析Java中AffineTransform類的使用

初步解析Java中AffineTransform類的使用
對比可知,仿射變換的順序是不能隨便交換的。

延伸 · 閱讀

精彩推薦
1120
主站蜘蛛池模板: 91在线精品一区二区三区 | 欧美一级二级视频 | 久久69精品久久久久久国产越南 | 久久99精品久久久久久国产越南 | 色视频网 | 色综合久久久久久久久久久 | 欧美午夜精品久久久久久浪潮 | 天天综合天天做天天综合 | 91视视频在线观看入口直接观看 | 午夜久久久 | 精品在线一区二区三区 | 国产精品成人一区二区三区夜夜夜 | 欧美a在线 | 天堂成人av| 欧美一区| 久久99国产一区二区三区 | 国产毛片av | 午夜爱爱毛片xxxx视频免费看 | 国产欧美精品一区二区三区 | 亚洲不卡在线观看 | 免费一级在线 | 91久久| 久久综合久久久 | 日本黄色免费网站 | 欧美日韩久久精品 | 亚洲天堂av影院 | 直接看av的网站 | 亚洲第一黄 | 亚洲男人天堂2018 | 成人网在线视频 | 国产精品久久久久久久久久久久久久 | 久久久久久久av | 国产成人精品久久 | 成人在线观看网 | 成人中文网 | 欧美在线小视频 | 在线观看亚洲 | 中文字幕一区在线 | 亚洲在线播放 | 亚洲精品国产成人 | 黄色在线免费看 |