国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

貓頭鷹的深夜翻譯:Java 2D Graphics, 簡單的仿射變換

whinc / 1690人閱讀

摘要:什么是仿射變換一組設(shè)備無關(guān)的坐標(biāo)被用來將所有的坐標(biāo)信息傳遞給對象。對象作為對象狀態(tài)的一部分。類代表一個(gè)的仿射變化,將一組的坐標(biāo)進(jìn)行線性映射到另一組保留了平行關(guān)系和豎直關(guān)系的坐標(biāo)中。

什么是仿射變換

一組設(shè)備無關(guān)的坐標(biāo)被用來將所有的坐標(biāo)信息傳遞給Graphics2D對象。AffineTransform對象作為Graphics2D對象狀態(tài)的一部分。該對象定義了如何將用戶空間的坐標(biāo)轉(zhuǎn)化為設(shè)備空間的設(shè)備相關(guān)的坐標(biāo)點(diǎn)。

AffineTransform類代表一個(gè)2D的仿射變化,將一組2D的坐標(biāo)進(jìn)行線性映射到另一組保留了平行關(guān)系和豎直關(guān)系的2D坐標(biāo)中。該轉(zhuǎn)化包括平移,縮放,翻轉(zhuǎn),旋轉(zhuǎn)和扭曲。

根據(jù)AffineTransform定義的變化有兩個(gè)非常重要的屬性:
直線依然是直線
平行的線依然保持平行

AffineTransform是限次那個(gè)轉(zhuǎn)化,所以可以通過矩陣的形式表示轉(zhuǎn)化,然以一個(gè)AffineTransform可以通過數(shù)學(xué)的形式轉(zhuǎn)化為一個(gè)包含六個(gè)數(shù)字的矩陣。
sx shx tx
shy sy ty

這里省略了矩陣的大括號。

不要方!

不要擔(dān)心看不懂矩陣。你不需要了解矩陣運(yùn)算的一切。你只需要有些許的基礎(chǔ)知識(shí)即可。

事實(shí)上,你甚至不用擔(dān)心需要理解一般的矩陣運(yùn)算來完成接下來我將說明的簡單轉(zhuǎn)換,但是這些可以幫助你更好的理解它是如何運(yùn)作的。

矩陣?yán)锏姆柖即砩叮?/b>

我將說明如何使用AffineTransform使圖片在展示于外設(shè)之前進(jìn)行下列轉(zhuǎn)換:

縮放

平移

扭曲

旋轉(zhuǎn)

在上面的矩陣中,sxsy代表縮放的比例,txty是實(shí)現(xiàn)平移的參數(shù)。shxshy是實(shí)現(xiàn)扭曲的參數(shù)。

旋轉(zhuǎn)實(shí)際上是縮放和扭曲的組合,所以它可以由上面的參數(shù)組合完成操作。

如何使用這些參數(shù)?
// ‘*’ 代表乘號
newX = sx*x + shx*y + tx
newY = shy*x + sy*y + ty

假設(shè)在用戶空間中存在坐標(biāo)(x, y),這些參數(shù)將通過上面的公式計(jì)算出新的坐標(biāo),從而實(shí)現(xiàn)縮放,扭曲和平移。

我們后面會(huì)看到,如果表示剪切和平移的因子的值為零,那么將不執(zhí)行該類型的變換。如果縮放的值為1(默認(rèn)值),那么圖片不會(huì)進(jìn)行縮放。其它的任何值都會(huì)導(dǎo)致縮放,平移或扭曲的發(fā)生。

對于所有三種類型的變換,用于變換x坐標(biāo)的值與用于變換y坐標(biāo)的值無關(guān)。因此,例如,可以對x進(jìn)行大樹枝的平移,并在y中用進(jìn)行小數(shù)值平移。

在詳細(xì)描述執(zhí)行這些轉(zhuǎn)換之前,對每個(gè)轉(zhuǎn)換提供些許解釋可能會(huì)很有用。

縮放

縮放可能是四種轉(zhuǎn)化中最好理解的一種。它是指如果一個(gè)點(diǎn)在用戶空間中的坐標(biāo)為(x,y),那么它在設(shè)備空間中的坐標(biāo)為(sx * x, sy * y )。乘數(shù)sxsy可以為正數(shù)或是負(fù)數(shù)。

平移

平移的目的是在設(shè)備空間中移動(dòng)坐標(biāo)系的原點(diǎn)。

比如,默認(rèn)的原點(diǎn)是組件左上角的點(diǎn)。假設(shè)組件是一個(gè)邊長四英寸的Frame,你可能希望原點(diǎn)位于框架的中心,而不是左上角。你可以通過將原點(diǎn)坐標(biāo)分別從水平和垂直方向平移兩英寸實(shí)現(xiàn)。

另一個(gè)使用平移的場景(與縮放同時(shí)使用)是翻轉(zhuǎn)垂直軸的默認(rèn)正方向,從而使y軸值的增加使得點(diǎn)向上移動(dòng)而不是默認(rèn)的向下移動(dòng)。

扭曲

這是網(wǎng)上給的一個(gè)shearing的圖例,即將原圖以平行四邊形拉伸。

旋轉(zhuǎn)

旋轉(zhuǎn)從視覺上很好理解。為了可視化旋轉(zhuǎn),在一張紙上畫一張照片。 使用一個(gè)釘子將其粘到公告板上。 然后圍繞大頭釘旋轉(zhuǎn)紙張。

在Java 2D中,旋轉(zhuǎn)是使用radians而不是degree的形式傳入?yún)?shù)。如果您不熟悉使用弧度度量來指定角度,請記住以下標(biāo)識(shí):

PI radians = 180 degrees

PI是在幾何類中學(xué)到的數(shù)值。它的值為3.14159...........。但是,你無須記住PI的數(shù)值,因?yàn)镸ATH類中包含了它的靜態(tài)值。你可以通過Math.PI獲得該值。

還有一個(gè)需要關(guān)注的是正角度的旋轉(zhuǎn)代表順時(shí)針旋轉(zhuǎn)。

簡單的程序

我們來看看一些代碼,并且學(xué)習(xí)使用Java 2D實(shí)現(xiàn)縮放,平移,扭曲和旋轉(zhuǎn)。

可疊加但不可交換

你會(huì)發(fā)現(xiàn)執(zhí)行兩個(gè)或是多個(gè)變化帶來的結(jié)果是累加的,但是不是可交換的。比如,執(zhí)行平移和旋轉(zhuǎn)并不一定等于先旋轉(zhuǎn)再平移得到的結(jié)果。

6個(gè)參數(shù)

執(zhí)行相應(yīng)操作時(shí)對應(yīng)的矩陣參數(shù)如下:

默認(rèn)
1.0 0.0 0.0
0.0 1.0 0.0 

添加縮放轉(zhuǎn)換
1.6666666666666667 0.0 0.0 
0.0 1.6666666666666667 0.0  

添加平移轉(zhuǎn)換
1.6666666666666667 0.0 30.0 
0.0 1.6666666666666667 30.0  

添加扭曲轉(zhuǎn)換
1.6666666666666667 0.08333333333333334 30.0
0.16666666666666669 1.666666666666666730.0 

添加旋轉(zhuǎn)轉(zhuǎn)換
1.6508996608400615 -0.2434184299932779 79.32270275806317 
0.4886147500940855 1.6021270803360292 -7.066823581936546
完整代碼
import java.awt.geom.*;
import java.awt.*;
import java.awt.event.*;
 
class Affine01{
  publicstaticvoid main(String[] args){
    GUI guiObj = new GUI();
  }//end main
}//end controlling class Affine01
 
class GUI extends Frame{
  int res;//store screen resolution here
  staticfinalint ds = 72;//default scale, 72 units/inch
  
  GUI(){//constructor
    //Get screen resolution
    res = Toolkit.getDefaultToolkit().
                           getScreenResolution();
 
    //Set Frame size to four-inches by four-inches
    this.setSize(4*res,4*res);
    this.setVisible(true);
    this.setTitle("Copyright 1999, R.G.Baldwin");
       
    //Window listener to terminate program.
    this.addWindowListener(new WindowAdapter(){
      publicvoid windowClosing(WindowEvent e){
        System.exit(0);}});
  }//end constructor
  
  //Override the paint() method to draw and manipulate a
  // square.
  publicvoid paint(Graphics g){
    //Downcast the Graphics object to a Graphics2D object
    Graphics2D g2 = (Graphics2D)g;
 
    //Display contents of default AffineTransform object
    System.out.println("Default Transform");
    displayMatrix(g2.getTransform());    
    
    //Update transform to include a scale component, 
    // and display the values.
    System.out.println("Add Scale Transform");
    g2.scale((double)res/72,(double)res/72);
    displayMatrix(g2.getTransform());
 
    //Update transform to include a translate component, 
    // and display the values.
    System.out.println("Add Translate Transform");
    g2.translate(0.25*ds,0.25*ds);
    displayMatrix(g2.getTransform());
 
    //Update transform to include a shear component, 
    // and display the values.
    System.out.println("Add Shear Transform");
    g2.shear(0.05,0.1);
    displayMatrix(g2.getTransform());
 
    //Update transform to provide rotation and display, 
    // the transform values.    
    System.out.println("Add Rotate Transform");
    //11.25 degrees about center
    g2.rotate(Math.PI/16,2.0*ds, 2.0*ds);
    displayMatrix(g2.getTransform());
 
    //Draw five concentric squares and apply the transform
    // that results from the above transform updates.  If
    // the above scale transform is applied, the outer
    // square is one inch on each side, and the squares
    // are separated by 0.1 inch 
    double delta = 0.1;
    for(int cnt = 0; cnt < 5; cnt++){
      g2.draw(new Rectangle2D.Double(
         (1.5+cnt*delta)*ds, (1.5+cnt*delta)*ds, 
         (1.0-cnt*2*delta)*ds, (1.0-cnt*2*delta)*ds));
    }//end for loop
 
    //Superimpose some text on the squares with the 
    // lower left corner of the first character at the
    // center of the squares.
    g2.drawString("Exit ->",2.0f*ds,2.0f*ds);
  }//end overridden paint()
    
  //This method receives a reference to an AffineTransform
  // and displays the six controllable values in the
  // transform matrix
  void displayMatrix(AffineTransform theTransform){
    double[] theMatrix = newdouble[6];
    theTransform.getMatrix(theMatrix);
    
    //Display first row of values by displaying every
    // other element in the array starting with element
    // zero.
    for(int cnt = 0; cnt < 6; cnt+=2){
      System.out.print(theMatrix[cnt] + " ");
    }//end for loop
    
    //Display second row of values displaying every
    // other element in the array starting with element
    // number one.
    System.out.println();//new line
    for(int cnt = 1; cnt < 6; cnt+=2){
      System.out.print(theMatrix[cnt] + " ");
    }//end for loop
    System.out.println();//end of line
    System.out.println();//blank line
    
  }//end displayMatrix
}//end class GUI
//==============================//


想要了解更多開發(fā)技術(shù),面試教程以及互聯(lián)網(wǎng)公司內(nèi)推,歡迎關(guān)注我的微信公眾號!將會(huì)不定期的發(fā)放福利哦~

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/69044.html

相關(guān)文章

  • 頭鷹深夜翻譯:JDK Vs. JRE Vs. JVM之間區(qū)別

    摘要:什么是為執(zhí)行字節(jié)碼提供一個(gè)運(yùn)行環(huán)境。它的實(shí)現(xiàn)主要包含三個(gè)部分,描述實(shí)現(xiàn)規(guī)格的文檔,具體實(shí)現(xiàn)和滿足要求的計(jì)算機(jī)程序以及實(shí)例具體執(zhí)行字節(jié)碼。該類先被轉(zhuǎn)化為一組字節(jié)碼并放入文件中。字節(jié)碼校驗(yàn)器通過字節(jié)碼校驗(yàn)器檢查格式并找出非法代碼。 什么是Java Development Kit (JDK)? JDK通常用來開發(fā)Java應(yīng)用和插件。基本上可以認(rèn)為是一個(gè)軟件開發(fā)環(huán)境。JDK包含Java Run...

    blair 評論0 收藏0
  • 頭鷹深夜翻譯Java WeakHashMap

    摘要:本文簡介類概覽類構(gòu)造器總結(jié)類構(gòu)造方法類使用舉例類概覽是一個(gè)實(shí)現(xiàn)了接口,并且鍵為型的哈希表。中的條目不再被正常使用時(shí),會(huì)被自動(dòng)刪除。它的鍵值均支持。和絕大多數(shù)的集合類一樣,這個(gè)類不是同步的。 本文簡介 WeakHashMap類概覽 WeakHashMap類構(gòu)造器總結(jié) WeakHashMap類構(gòu)造方法 WeakHasjMap類使用舉例 1. WeakHashMap類概覽 Wea...

    BothEyes1993 評論0 收藏0
  • 頭鷹深夜翻譯JavaCAS(Compare And Swap)

    摘要:否則它就會(huì)用新的值替代當(dāng)前值。在這種情況下,鎖可能會(huì)優(yōu)于原子變量,但在實(shí)際的爭用級別中,原子變量的性能優(yōu)于鎖。在中引入了另外一個(gè)構(gòu)件。 題目要求 在我們深入了解CAS(Compare And Swap)策略以及它是如何在AtomicInteger這樣的原子構(gòu)造器中使用的,首先來看一下這段代碼: public class MyApp { private volatile int ...

    hosition 評論0 收藏0
  • 頭鷹深夜翻譯:使用JAVA CompletableFuture20例子

    摘要:這個(gè)例子想要說明兩個(gè)事情中以為結(jié)尾的方法將會(huì)異步執(zhí)行默認(rèn)情況下即指沒有傳入的情況下,異步執(zhí)行會(huì)使用實(shí)現(xiàn),該線程池使用一個(gè)后臺(tái)線程來執(zhí)行任務(wù)。這個(gè)例子展示了如何使用一個(gè)固定大小的線程池來實(shí)現(xiàn)大寫操作。 前言 這篇博客回顧JAVA8的CompletionStageAPI以及其在JAVA庫中的標(biāo)準(zhǔn)實(shí)現(xiàn)CompletableFuture。將會(huì)通過幾個(gè)例子來展示API的各種行為。 因?yàn)镃ompl...

    AZmake 評論0 收藏0
  • 頭鷹深夜翻譯Java 10JEP 286-局部變量類型推斷

    摘要:在此基礎(chǔ)上又向前邁進(jìn)了一步局部變量類型推斷允許開發(fā)人員跳過局部變量的類型聲明局部變量是指在方法定義,初始化塊,循環(huán)和其它的如代碼塊,會(huì)推斷該局部變量的類型。 前言 之前面試的時(shí)候問了我是否了解JDK10的變化,一時(shí)回答不出來,所以只回答了JDK8中的函數(shù)式編程和流編程。今天看到這篇講JAVA10的文章,順便了解一下。 正文 JAVA10的所有新特性請參考這里。在所有的JEP中,JEP-...

    chavesgu 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<