2014-09-18 61 views
1

我在Java中有一個簡單的動畫,它由一個在窗戶上移動的輪子組成。這只是一個簡單的圓圈,從左側的屏幕開始,進入並繼續向右,直到它離開屏幕。然後它循環並重復這個過程。簡單的圓形旋轉(模擬運動)

X是一個包含車輪位置的變量。它可以在 - (車輪寬度)和車窗尺寸+車輪寬度之間。

我想通過在這個輪子內繪製一個圓來模擬旋轉,它圍繞圓旋轉,就好像它被連接一樣。

想象一下現實生活中帶有紅旗的車輪。隨着車輪轉動,紅色標記將位於車輪邊緣,隨着車輪的進展而移動。這是我想要的行爲。

我得到一個百分比傳遞到我輪類是這樣的:

int percentage = x/windowWidth; 

每一幀的輪動作,我打電話wheel.rotate(percentage)

這是實現:

private int diameter = 50;   
private final int SPOKE_DIAMETER = diameter/5; 

    public void rotate(double percent){ 
     this.percent = percent; 
     this.theta = percent*(PI*2); 
     System.out.println(percent*PI); 
    } 

    public void paintComponent(Graphics canvas) 
    { 
     // wheel 
     canvas.setColor(Color.gray); 
     canvas.fillOval(0, 0, diameter, diameter); 

     // spinning flag 
     canvas.setColor(Color.red); 
     canvas.fillOval((int)(percent*diameter),(int)((sin((percent*(PI*2)))*diameter)), SPOKE_DIAMETER,SPOKE_DIAMETER); 
    } 

x位置工作或多或少我怎麼想,但Y不。它像一個正弦波擺動,這是預期的(我使用罪...),但是,我不知道如何改變我的數學,以跟隨周圍的圓。

我的實現有什麼問題? (我不是很好用三角函數圖)

+0

那麼,你可以簡單地旋轉'Graphics'上下文...... – MadProgrammer 2014-09-18 22:36:34

+0

是的!如果可以的話,我肯定會這樣做,除非我正在嘗試使用數學(這是一個學校項目)。 – 2014-09-18 22:37:37

+0

東西像http://stackoverflow.com/questions/12964983/rotate-image-around-character-java/12971987#12971987 – MadProgrammer 2014-09-18 22:40:21

回答

4

基本上,你需要計算圓上的點,基於該對象應該出現的角度...

最喜歡的事情,我偷了這一關互聯網的地方,但它的作品...

protected Point getPointOnCircle(float degress, float radius) { 

    int x = Math.round(getWidth()/2); 
    int y = Math.round(getHeight()/2); 

    double rads = Math.toRadians(degress - 90); // 0 becomes the top 

    // Calculate the outter point of the line 
    int xPosy = Math.round((float) (x + Math.cos(rads) * radius)); 
    int yPosy = Math.round((float) (y + Math.sin(rads) * radius)); 

    return new Point(xPosy, yPosy); 

} 

基於(度)的天使和圓的半徑,這將返回X/Y軸沿圓的周長。 ..

Rotate within

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class RotateWheel { 

    public static void main(String[] args) { 
     new RotateWheel(); 
    } 

    public RotateWheel() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private float degrees = 0; 

     public TestPane() { 
      Timer timer = new Timer(40, new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        degrees += 0.5f; 
        repaint(); 
       } 
      }); 
      timer.start(); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(200, 200); 
     } 

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

      int diameter = Math.min(getWidth(), getHeight()); 
      int x = (getWidth() - diameter)/2; 
      int y = (getHeight() - diameter)/2; 

      g2d.setColor(Color.GREEN); 
      g2d.drawOval(x, y, diameter, diameter); 

      g2d.setColor(Color.RED); 
      float innerDiameter = 20; 

      Point p = getPointOnCircle(degrees, (diameter/2f) - (innerDiameter/2)); 
      g2d.drawOval(x + p.x - (int) (innerDiameter/2), y + p.y - (int) (innerDiameter/2), (int) innerDiameter, (int) innerDiameter); 

      g2d.dispose(); 
     } 

     protected Point getPointOnCircle(float degress, float radius) { 

      int x = Math.round(getWidth()/2); 
      int y = Math.round(getHeight()/2); 

      double rads = Math.toRadians(degress - 90); // 0 becomes the top 

      // Calculate the outter point of the line 
      int xPosy = Math.round((float) (x + Math.cos(rads) * radius)); 
      int yPosy = Math.round((float) (y + Math.sin(rads) * radius)); 

      return new Point(xPosy, yPosy); 

     } 

    } 

} 
+0

+1爲'生活'的介紹。問:用什麼來做到這一點? – adhg 2014-09-19 00:16:30

+0

@adhg [LICEcap](http://www.cockos.com/licecap/),它是免費的並且跨平臺 – MadProgrammer 2014-09-19 00:17:45