2011-04-14 27 views
5

我一直在使用仿射變換在我的Java項目轉動一個字符串,而我不是一個有經驗的程序員還沒有,所以它走了很長的時間做一個看似小的任務。要旋轉的字符串。如何仿射變換真的Java的工作?

現在我終於可以像我希望的那樣或多或少地工作了,除非它不像我想要的那麼精確。

由於花了很多試驗和錯誤,並閱讀了仿射變換的描述,我仍然不太確定它的真實含義。我想我知道的那一刻,是我有一個字符串,並定義字符串(或者我要繞點)的中心,但哪裏矩陣來到這個? (顯然我不知道嘿嘿)

任何人都可以嘗試和向我解釋仿射變換是如何工作的,換句話說,比java文檔?也許它可以幫助我調整我的實現,也是,我只是真的想知道:)

在此先感謝。

+2

這是一個比編程更多的數學問題。查看維基百科關於它的頁面: http://en.wikipedia.org/wiki/Affine_transformation 不是說它比JavaDoc更容易理解。 :)不幸的是,這只是你必須蠻橫逼迫你學習的其中一件事,恕我直言。 – brindy 2011-04-14 21:58:02

回答

5

要了解什麼是仿射變換,它的工作原理看維基百科article

一般來說,它是一種線性變換(如縮放或反射),可以通過特定矩陣的乘法實現,然後是通過添加矢量完成的平移(移動)。如此計算每個像素[X,Y]需要由特定的矩陣乘以它的新位置(執行線性變換),然後添加然後添加的特定載體(做翻譯)。

2

作爲一個實際問題,我發現在理解AffineTransform有用的兩件事情:

  1. 您可以將任意一個圖形上下文,Graphics2D,或實現Shape接口的任何類,如討論here

  2. 級聯轉換有一個明顯的最後指定優先訂單,也提到here

2
從我想展示一個實際的尖端即旋轉字符串或其他對象時,我通常採用的模式已經被其他給出的答案

除了:

  1. 移動旋轉點(X,Y )對空間應用translate(-x,-y)原點。
  2. 做旋轉rotate(angle)(也可能縮放將在這裏完成)
  3. 將所有內容移回原始點translate(x,y)

請記住,您必須以相反的順序應用這些步驟(請參閱垃圾回答)。

對於第一次翻譯的字符串,我通常會將邊界框的中心移動到原點,並使用最後一個翻譯將字符串移動到中心應該出現在屏幕上的實際點。然後,我可以簡單地在任何我喜歡的位置繪製字符串。

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g); 
g.translate(final_x, final_y); 
g.rotate(-angle); 
g.translate(-r.getCenterX(), -r.getCenterY()); 
g.drawString(text, 0, 0); 

或替代地

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g); 
AffineTransform trans = AffineTransform.getTranslateInstance(final_x, final_y); 
trans.concatenate(AffineTransform.getRotateInstance(-angle)); 
trans.concatenate(AffineTransform.getTranslateInstance(-r.getCenterX(), -r.getCenterY())); 
g.setTransform(trans); 
g.drawString(text, 0, 0); 
3

除了其他的答案,更高的水平視圖:在屏幕上

  • 的點有ax和y座標,即,可以被寫爲一個向量(x,y)。更復雜的幾何對象可以被認爲是由一組點描述的。

  • 向量(點)可以乘以一個矩陣,結果是另一個向量(點)。

  • 有一些特殊的(即巧妙構造的)矩陣,當與矢量相乘時產生的結果向量相當於旋轉,縮放,傾斜或輸入點的一些欺騙性轉換。

基本上就是這樣。這種方法還有幾個奇特的特徵:

  • 如果你乘以2矩陣,你再次得到一個矩陣(至少在這種情況下;停止挑選;-))。
  • 如果您乘以2矩陣相當於2幾何變換,結果矩陣相當於做2個幾何變換一個接一個(順序重要btw)。
  • 這意味着您可以在單個矩陣中對這些幾何變換的任意鏈進行編碼。你可以通過乘以單個矩陣來創建這個矩陣。
  • 順便說一句,這也適用於3D。

欲瞭解更多詳情,請參閱其他答案。