2012-11-22 63 views
2

嗨!旋轉矩形並將其移動到正弦波 - 幫助使用graphics2D

我有下面的代碼使用以前的Stackoverflow的職位。

我想只是旋轉矩形的某個角度,並使其在正弦波中移動。

該代碼也旋轉整個正弦波。

我明白爲什麼會發生,但我不知道如何達到我的目的。

請幫忙!!!

非常感謝您抽出時間。

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.geom.AffineTransform; 
import java.util.Timer; 
import java.util.TimerTask; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class Withrotation { 

    public static int i = 1; 
    public static Ticker t; 
    public static Repainter r; 
    public static int newx, newy; 

    public static void main(String[] args) { 
     final JFrame frame = new JFrame("Wavy!"); 
     final WavyPanel wp = new WavyPanel(); 
     frame.getContentPane().add(wp, BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     t = new Ticker(wp); 
     r = new Repainter(wp); 
     frame.pack(); 
     frame.setVisible(true); 
     final Timer tickTimer = new Timer(); 
     final Timer paintTimer = new Timer(); 
     paintTimer.schedule(r, 1000, 50); 
     tickTimer.schedule(t, 1000, 10); 
    } 

    private static class WavyPanel extends JPanel { 

     private final Dimension size = new Dimension(640, 480); 
     private int amplitude = 50; 
     private int frequency = 5; 
     private double x1 = 0; 
     private double y1 = 500; 
     private int yBase = 0; 

     WavyPanel() { 
      super(true); 
     } 

     @Override 
     protected void paintComponent(final Graphics g) { 
      final Graphics2D g2 = (Graphics2D) g; 
      AffineTransform old = g2.getTransform(); 
      g2.rotate(Math.toRadians(-30)); 

      g2.clearRect(0, 0, this.getSize().width, this.getSize().height); 
      g2.setColor(Color.BLACK); 
      g2.fillRect((int) x1, (int) y1, 20, 80); 
      g2.setTransform(old); 


     } 

     @Override 
     public Dimension getPreferredSize() { 
      return size; 
     } 

     @Override 
     public Dimension getMinimumSize() { 
      return size; 
     } 

     @Override 
     public Dimension getMaximumSize() { 
      return size; 
     } 

     public void tick() { 
      x1 = x1 + 1; 
      final int waveLength = size.width/frequency; 
      yBase = (++yBase) % waveLength; 
      final double normalized = (double) yBase/(double) waveLength; 
      final double radians = normalized * Math.PI * 2; 
      final double sine = Math.sin(radians); 
      y1 = (int) (sine * amplitude); 




     } 
    } 

    private static class Ticker extends TimerTask { 

     private final WavyPanel panel; 

     Ticker(final WavyPanel panel) { 

      this.panel = panel; 

     } 

     @Override 
     public void run() { 
      panel.tick(); 
     } 
    } 

    private static class Repainter extends TimerTask { 

     private final WavyPanel panel; 

     Repainter(final WavyPanel panel) { 

      this.panel = panel; 

     } 

     @Override 
     public void run() { 
      panel.repaint(); 

     } 
    } 
} 

回答

5

+1 SSCCE

1)不要忘記在調用super.paintComponent();在你重寫paintComponent(..)法第一條語句。

2)搖擺UI應EDT創建並結合Swing Timers

3)Java變量命名約定用於類爲每一個新的字即WithRotation大寫字母。

4)不需要frame.getContentPane.add(..)只需使用add(..),因爲所有呼叫都被轉發到它的contentPane

這裏是我提出(基本上是與上述修復代碼實現),其中僅旋轉下面的曲線圖,而不是整個圖形對象使用AffineTransform#createTransformedShape()矩形的例子:

enter image description here

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Rectangle; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.geom.AffineTransform; 
import javax.swing.AbstractAction; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class WithRotation { 

    private JFrame frame; 
    private WavyPanel wp; 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       new WithRotation(); 
      } 
     }); 
    } 

    public WithRotation() { 
     initComponents(); 
    } 

    private void initComponents() { 
     frame = new JFrame("Wavy!"); 
     wp = new WavyPanel(); 
     frame.add(wp, BorderLayout.CENTER); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 

     createAndStartTimers(); 
    } 

    private void createAndStartTimers() { 
     new Timer(50, new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 

       wp.repaint(); 
      } 
     }).start(); 
     new Timer(10, new AbstractAction() { 
      @Override 
      public void actionPerformed(ActionEvent ae) { 

       wp.tick(); 
      } 
     }).start(); 
    } 

    class WavyPanel extends JPanel { 

     private final Dimension size = new Dimension(640, 480); 
     private int amplitude = 50; 
     private int frequency = 5; 
     private double x1 = 0; 
     private double y1 = 500; 
     private int yBase = 0; 

     WavyPanel() { 
      super(true); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2 = (Graphics2D) g; 

      g2.clearRect(0, 0, this.getSize().width, this.getSize().height); 
      g2.setColor(Color.BLACK); 

      Rectangle rect = new Rectangle((int) x1, (int) y1, 20, 80); 

      AffineTransform transform = new AffineTransform(); 
      transform.rotate(Math.toRadians(-30), rect.getX() + rect.width/2, rect.getY() + rect.height/2); 

      Shape transformed = transform.createTransformedShape(rect); 
      g2.fill(transformed); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return size; 
     } 

     @Override 
     public Dimension getMinimumSize() { 
      return size; 
     } 

     @Override 
     public Dimension getMaximumSize() { 
      return size; 
     } 

     public void tick() { 
      x1 = x1 + 1; 
      final int waveLength = size.width/frequency; 
      yBase = (++yBase) % waveLength; 
      final double normalized = (double) yBase/(double) waveLength; 
      final double radians = normalized * Math.PI * 2; 
      final double sine = Math.sin(radians); 
      y1 = (int) (sine * amplitude); 
     } 
    } 
} 
+0

呀這是我通常得到的輸出,這個代碼使得輸出變得完美!但是我需要的是那個矩形旋轉一定的角度,並且仍然在相同的Sin Wave中移動。當我使用旋轉時,整個sin波也旋轉,但我只想要矩形旋轉。希望我很清楚。謝謝你的回覆。 – Yash

+0

@Yash我看會更新很快 –

+0

非常感謝:D – Yash