亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

初步解析Java中AffineTransform類的使用

 更新時(shí)間:2015年10月16日 09:06:13   作者:computingbear  
這篇文章主要介紹了Java中AffineTransform類的使用,AffineTransform類經(jīng)常被用來處理圖片,需要的朋友可以參考下

AffineTransform類描述了一種二維仿射變換的功能,它是一種二維坐標(biāo)到二維坐標(biāo)之間的線性變換,保持二維圖形的“平直性”(譯注:straightness,即變換后直線還是直線不會(huì)打彎,圓弧還是圓?。┖汀捌叫行浴保ㄗg注:parallelness,其實(shí)是指保二維圖形間的相對(duì)位置關(guān)系不變,平行線還是平行線,相交直線的交角不變。大二學(xué)過的復(fù)變,“保形變換/保角變換”都還記得吧,數(shù)學(xué)就是王道?。。7律渥儞Q可以通過一系列的原子變換的復(fù)合來實(shí)現(xiàn),包括:平移(Translation)、縮放(Scale)、翻轉(zhuǎn)(Flip)、旋轉(zhuǎn)(Rotation)和剪切(Shear)。

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

[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 ] 


幾種典型的仿射變換:

public static AffineTransform getTranslateInstance(double tx, double ty) 


平移變換,將每一點(diǎn)移動(dòng)到(x+tx, y+ty),變換矩陣為:

[ 1 0 tx ] 
[ 0 1 ty ] 
[ 0 0 1 ] 


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

public static AffineTransform getScaleInstance(double sx, double sy) 


縮放變換,將每一點(diǎn)的橫坐標(biāo)放大(縮小)至sx倍,縱坐標(biāo)放大(縮小)至sy倍,變換矩陣為:

[ sx 0 0 ] 
[ 0 sy 0 ] 
[ 0 0 1 ] 

public static AffineTransform getShearInstance(double shx, double shy) 

剪切變換,變換矩陣為:

[ 1 shx 0 ] 
[ shy 1 0 ] 
[ 0 0 1 ] 

相當(dāng)于一個(gè)橫向剪切與一個(gè)縱向剪切的復(fù)合

[ 1 0 0 ][ 1 shx 0 ] 
[ shy 1 0 ][ 0 1 0 ] 
[ 0 0 1 ][ 0 0 1 ] 


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

public static AffineTransform getRotateInstance(double theta) 


旋轉(zhuǎn)變換,目標(biāo)圖形圍繞原點(diǎn)順時(shí)針旋轉(zhuǎn)theta弧度,變換矩陣為:

[ cos(theta) -sin(theta) 0 ] 

[ sin(theta) cos(theta) 0 ] 
[ 0 0 1 ] 


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

旋轉(zhuǎn)變換,目標(biāo)圖形以(x, y)為軸心順時(shí)針旋轉(zhuǎn)theta弧度,變換矩陣為:

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


相當(dāng)于兩次平移變換與一次原點(diǎn)旋轉(zhuǎn)變換的復(fù)合:

[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] 

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

可以簡(jiǎn)單地表示為:y = Ax + b ,其中有下標(biāo)的字母表示向量,而粗體的字母A表示一個(gè)矩陣。

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

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

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();
 }

}


對(duì)比可知,仿射變換的順序是不能隨便交換的。

相關(guān)文章

  • Java實(shí)現(xiàn)bmp和jpeg圖片格式互轉(zhuǎn)

    Java實(shí)現(xiàn)bmp和jpeg圖片格式互轉(zhuǎn)

    本文主要介紹了Java實(shí)現(xiàn)bmp和jpeg圖片格式互轉(zhuǎn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • springboot中json對(duì)象中對(duì)Long類型和String類型相互轉(zhuǎn)換

    springboot中json對(duì)象中對(duì)Long類型和String類型相互轉(zhuǎn)換

    與前端聯(lián)調(diào)接口時(shí),后端一些字段設(shè)計(jì)為L(zhǎng)ong類型,這樣就有可能導(dǎo)致前端缺失精度,這時(shí)候我們就需要將Long類型返回給前端時(shí)做數(shù)據(jù)類型轉(zhuǎn)換,本文主要介紹了springboot中json對(duì)象中對(duì)Long類型和String類型相互轉(zhuǎn)換,感興趣的可以了解一下
    2023-11-11
  • springboot配置多數(shù)據(jù)源后mybatis攔截器失效的解決

    springboot配置多數(shù)據(jù)源后mybatis攔截器失效的解決

    這篇文章主要介紹了springboot配置多數(shù)據(jù)源后mybatis攔截器失效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • SpringBoot集成JWT生成token及校驗(yàn)方法過程解析

    SpringBoot集成JWT生成token及校驗(yàn)方法過程解析

    這篇文章主要介紹了SpringBoot集成JWT生成token及校驗(yàn)方法過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • 詳解Java的四種引用方式及其區(qū)別

    詳解Java的四種引用方式及其區(qū)別

    這篇文章主要介紹了Java的四種引用方式 ,主要主要包括強(qiáng)引用,軟引用,弱引用,虛引用,稍微整理精簡(jiǎn)一下做下分享,具有一定的參考價(jià)值,需要的朋友可以參考下
    2018-12-12
  • Java中l(wèi)ock和tryLock及l(fā)ockInterruptibly的區(qū)別

    Java中l(wèi)ock和tryLock及l(fā)ockInterruptibly的區(qū)別

    這篇文章主要介紹了Java中l(wèi)ock和tryLock及l(fā)ockInterruptibly的區(qū)別,文章介紹詳細(xì),具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • Java中的FutureTask實(shí)現(xiàn)異步任務(wù)代碼實(shí)例

    Java中的FutureTask實(shí)現(xiàn)異步任務(wù)代碼實(shí)例

    這篇文章主要介紹了Java中的FutureTask實(shí)現(xiàn)異步任務(wù)代碼實(shí)例,普通的線程執(zhí)行是無法獲取到執(zhí)行結(jié)果的,FutureTask?間接實(shí)現(xiàn)了?Runnable?和?Future?接口,可以得到子線程耗時(shí)操作的執(zhí)行結(jié)果,AsyncTask?異步任務(wù)就是使用了該機(jī)制,需要的朋友可以參考下
    2024-01-01
  • 淺析SpringBoot中常見的底層注解

    淺析SpringBoot中常見的底層注解

    Spring?Boot?是一個(gè)用于創(chuàng)建獨(dú)立的、基于Spring框架的Java應(yīng)用程序的框架,它提供了許多注解,下面小編就來和大家介紹一些常見的底層注解吧
    2023-08-08
  • springboot?使用clickhouse實(shí)時(shí)大數(shù)據(jù)分析引擎(使用方式)

    springboot?使用clickhouse實(shí)時(shí)大數(shù)據(jù)分析引擎(使用方式)

    這篇文章主要介紹了springboot?使用clickhouse實(shí)時(shí)大數(shù)據(jù)分析引擎的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-02-02
  • Java使用Collections.sort()排序的示例詳解

    Java使用Collections.sort()排序的示例詳解

    這篇文章主要介紹了Java使用Collections.sort()排序的示例詳解,Collections.sort(list, new PriceComparator());的第二個(gè)參數(shù)返回一個(gè)int型的值,就相當(dāng)于一個(gè)標(biāo)志,告訴sort方法按什么順序來對(duì)list進(jìn)行排序。對(duì)此感興趣的可以了解一下
    2020-07-07

最新評(píng)論