2011-04-08 114 views
3

我有一個帶有x和y軸的二維圖形,我試圖圍繞一個軸旋轉一個形狀(一系列點)。這種輪換將需要包括一個比例函數。圍繞x軸垂直旋轉一個形狀

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.Point2D; 
import javax.swing.*; 
import java.lang.reflect.Array; 

public class test extends JPanel implements ActionListener { 

    int[] p1x = {200, 200, 240, 240, 220, 220, 200}; 
    int[] p1y = {200, 260, 260, 240, 240, 200, 200}; 
    int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600}; 
    int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400}; 
    int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400}; 
    int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400}; 
    int delay = 1000; 
    int dx = 0; 
    int dy = 5; 
    int steps = 121; 
    Polygon t; 
    Timer tim = new Timer(delay, this); 

    public void actionPerformed(ActionEvent event) { 
     for (int i = 0; i < Array.getLength(p2x); i++) { 
      //p2x[i] = (int) (p2x[i]*Math.cos(Math.toRadians(1))- p2y[i]*Math.sin(Math.toRadians(1))); 
      //p2y[i] = (int) (p2x[i]*Math.sin(Math.toRadians(1))+ p2y[i]*Math.cos(Math.toRadians(1)));; 

      Point2D original = new Point2D.Double(p2x[i], p2y[i]); 
      AffineTransform at = new AffineTransform(); 
      //at.setToRotation(.02, 250, 250); 
      at.scale(1, -1); 
      Point2D rotated = at.transform(original, null); 
      p2x[i] = (int) rotated.getX(); 
      p2y[i] = (int) rotated.getY(); 
     } 
     repaint(); 

     if (--steps == 0) { 
      tim.stop(); 
     } 
    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 

     this.setBackground(Color.white); 

     g.drawLine(this.getWidth()/2, 0, this.getWidth()/2, this.getWidth()); 
     g.drawLine(0, this.getHeight()/2, this.getHeight(), this.getHeight()/2); 

     Polygon t = new Polygon(p2x, p2y, 9); 
     g.drawPolygon(t); 

     Letters u = new Letters(p3x, p3y, 9); 
     u.draw(g); 

     Letters l = new Letters(p1x, p1y, 7); 
     l.draw(g); 
    } 

    public static void main(String[] args) { 

     JFrame frame = new JFrame("Drawing line and a moving polygon"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     test sl = new test(); 
     frame.getContentPane().add(sl); 
     frame.setSize(700, 700); 
     frame.setVisible(true); 

     sl.tim.start(); 
    } 
} 
+0

重新格式化的代碼;如果不正確請回復。 – trashgod 2011-04-08 09:30:55

回答

10

如果沒有明確的問題,使用座標數組的簡單動畫如下所示。一般來說,您可以轉換圖形上下文(​​)或多邊形Shape本身(p3);該示例顯示了兩者。調整窗口大小以查看每個效果。

注意最後指定優先轉換的順序在at。首先,將p3上的合適點翻譯爲原點,然後對p3進行縮放,然後將p3轉換爲面板的中心。適用於p3+ 10巧妙因素是沒有對稱旋轉點的僞影。定義相對於原點的多邊形可能更容易,如example所示。

AffineTest

import java.awt.*; 
import java.awt.event.*; 
import java.awt.geom.AffineTransform; 
import javax.swing.*; 

/** @see http://stackoverflow.com/questions/3405799 */ 
public class AffineTest extends JPanel implements ActionListener { 

    private static final double DELTA_THETA = Math.PI/45; // 4° 
    private static final double DELTA_SCALE = 0.1; 
    private int[] p1x = {200, 200, 240, 240, 220, 220, 200}; 
    private int[] p1y = {200, 260, 260, 240, 240, 200, 200}; 
    private int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600}; 
    private int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400}; 
    private int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400}; 
    private int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400}; 
    private Polygon p1 = new Polygon(p1x, p1y, p1x.length); 
    private Polygon p2 = new Polygon(p2x, p2y, p2x.length); 
    private Polygon p3 = new Polygon(p3x, p3y, p3x.length); 
    private AffineTransform at = new AffineTransform(); 
    private double dt = DELTA_THETA; 
    private double theta; 
    private double ds = DELTA_SCALE; 
    private double scale = 1; 
    private Timer timer = new Timer(100, this); 

    public AffineTest() { 
     this.setPreferredSize(new Dimension(700, 700)); 
     this.setBackground(Color.white); 
     p1.translate(-50, +100); 
     p2.translate(-100, -100); 
    } 

    @Override 
    public void actionPerformed(ActionEvent event) { 
     theta += dt; 
     scale += ds; 
     if (scale < .5 || scale > 4) { 
      ds = -ds; 
     } 
     repaint(); 
    } 

    @Override 
    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     Graphics2D g2d = (Graphics2D) g; 
     g2d.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     int w = this.getWidth(); 
     int h = this.getHeight(); 
     g2d.drawLine(w/2, 0, w/2, h); 
     g2d.drawLine(0, h/2, w, h/2); 
     g2d.rotate(theta, w/2, h/2); 
     g2d.drawPolygon(p1); 
     g2d.drawPolygon(p2); 
     at.setToIdentity(); 
     at.translate(w/2, h/2); 
     at.scale(scale, scale); 
     at.translate(-p3x[5] + 10, -p3y[5]); 
     g2d.setPaint(Color.blue); 
     g2d.fill(at.createTransformedShape(p3)); 
    } 

    public void start() { 
     timer.start(); 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Affine Test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     AffineTest sl = new AffineTest(); 
     frame.add(sl); 
     frame.pack(); 
     frame.setVisible(true); 
     sl.start(); 
    } 
} 
+0

謝謝你們,非常有幫助。幫助澄清一些混淆。我正在試圖圍繞x軸旋轉這些字母,而不是圍繞2D圖上的原點。請注意,通過縮放可以實現頂點向「z方向」(幀外)的旋轉;並且每個字母的座標軸相對於框架的座標軸具有相對位置。 – 2011-04-08 18:30:05

+1

非常好。有一個[sscce](http://sscce.org/)供參考是非常寶貴的;但是,因爲你是一名學生,所以我不想玩得很開心。 :-)您應該能夠通過在正交方向上縮放和平移來模擬圍繞軸的旋轉;離軸通常需要剪切。請考慮接受和/或投票處理此問題以及您收到的其他答案。 – trashgod 2011-04-08 19:28:53

+0

+1非常好我喜歡:) – 2013-01-05 08:02:23