2015-09-11 51 views
2

我正在嘗試編寫一個程序,該程序將繪製圍繞中心點旋轉的幾種形狀。結果應該像一個Spirograph。我試圖用矩形測試它,但我只能讓它們中的兩個出現在窗口中。其中一個是它應該在的位置,但是在第一次旋轉之後,它將另一個方形投影到窗口的左上角。它應該圍繞中心點旋轉和拉伸。這是我的代碼的一部分。在指定點周圍旋轉Java 2D圖形

import java.awt.*; 
import java.awt.geom.Ellipse2D; 

import javax.swing.JPanel; 

public class Shapes extends JPanel 
{ 
private double angle; 
private int type; 
private int radius; 
private int repeats; 

public Shapes(int t, int r, int z) 
{ 
    type = t; 
    radius = r; 
    repeats = z;  
    angle = 360/repeats; 
} 

public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D)g; 

    g.setColor(Color.red); 

    int centerX = getWidth()/2; 
    int centerY = getHeight()/2; 

    double curAngle = 0; 

    for(int i=0; i<=repeats; i+=1) 
    { 
     g.setColor(Color.blue); 

     Rectangle tangle = new Rectangle(0, 0, radius, radius); 
     g2d.rotate(Math.toRadians(curAngle)); 
     g2d.translate(centerX, centerY); 
     g2d.draw(tangle); 
     curAngle += angle; 
    } 

}

+0

類似[this](http://stackoverflow.com/questions/12964983/rotate-image-around-character-java/12971987#12971987)? – MadProgrammer

+0

小心旋轉和翻譯混合 – MadProgrammer

+0

就像這樣。 http://i.imgur.com/y6hAMV8.png –

回答

6

記住,translaterotate是複利,也就是每次應用它們的時候,它們添加到當前轉型。

有許多方法可以實現這一目標,但首先,我們需要複製Graphics上下文。這是一種重要的任何時候你惹變換特別是你用Graphics上下文的副本這樣做,因爲這會離開原來的影響(而不會影響任何可能被塗上之後)

Graphics2D g2d = (Graphics2D) g.create(); 
//... 
g2d.dispose(); 

,所以,只要你做的​​現在,會不會影響g

現在的狀態,我們可以使用的的「複利」效應轉化爲我們的優勢

Rectangle tangle = new Rectangle(0, 0, radius, radius); 
//g2d.translate(centerX, centerY); 
g2d.rotate(Math.toRadians(angle), centerX, centerY); 
g2d.draw(tangle); 

所以,這一切確實是將angle的值應用於每個循環中Graphics上下文的副本。錨點被設置爲centerXcenterY

Spiral 01

好吧,這看起來不錯,但如果我調整窗口的大小會發生什麼?

Spiral 02

好了,不是真的我所期待的。這是由於原因,形狀的大小,定位點,旋轉,平移偏移量等因素的綜合作用而產生的,這些都是爲了產生效果(冷卻儘管)。

好了,所以,相反,我們可以簡單地爲每個循環新的變換而不是,提供我們想要的確切參數,例如...

Graphics2D g2d = (Graphics2D) g.create(); 
g2d.setColor(Color.blue); 

Rectangle tangle = new Rectangle(0, 0, radius, radius); 
g2d.translate(centerX, centerY); 
g2d.rotate(Math.toRadians(curAngle)); 
g2d.draw(tangle); 
curAngle += angle; 
g2d.dispose(); 

這現在生產...

Spiral 03

在玩代碼時,我注意到當我增加重複次數時,我沒有得到期望的結果。

相同挖掘後,我改變

angle = 360/repeats; 

angle = 360.d/repeats; 

其停止整數除法的問題(和十進制值的截斷),並開始以產生期望的結果

簡單的比較前後...

BeforeAfter