2017-10-31 8 views
2

私はかなりJavaに慣れていて、月が地球の周りを回って太陽の周りを回転する簡単な太陽系をプログラムしたいと思っています。 月が正しく移動したくない場合を除き、すべてがうまくいきます。/ 地球が月の初期位置から離れているため、月の回転半径はその距離に応じて大きくなります。そして、地球が宇宙の慣性位置に近づくと、回転半径が減少します。 初期位置が(0; 0)の場合は動作しますが、月が太陽に当たっています...Javaで別の動くオブジェクトの周りにオブジェクトを回転させるには?

どのように地球と月の距離を一定に保つことができますか? 私はAffineTransformsを使用していますが、ここに私のコードのスニペットです;)

ありがとうございます!

Ellipse2D.Double MoonFrame = new Ellipse2D.Double(orbitEarth + orbitMoon - radiusMoon, -radiusMoon, radiusMoon*2, radiusMoon*2); 

for (int i = 0; i < 360; i++) 
    { 
    theta += Math.PI/30; 
    AffineTransform TransformMoon = AffineTransform.getRotateInstance(theta,TransformEarth.getTranslateX(),TransformEarth.getTranslateY()); 

    g2d.fill(TransformMond.createTransformedShape(MoonFrame)); 
    } 
+0

さて、[これは1 iは、デー](https://stackoverflow.com/questions/12964983/rotate-imagearound-character-java/12971987#12971987) – MadProgrammer

+0

あなたの基本的な質問はこれです。 「別のオブジェクトの周りに円があれば、中心からの角度に基づいて円上の点を見つける方法は?」今、あなたがこの質問に答えることができれば(円上の点を見つけてください)、基本的なレベルではありますが、答えはあなたにあります。残りは些細なものです – MadProgrammer

+0

これは特にSwingの質問ですか? – user1803551

答えて

0

だから、あなたの基本的な質問は真剣...「どのように私は所与の角度のための円上の点を見つけるのですか」に降りてくる、それは簡単な

は、グーグルの多くの時間に基づいていることです試行錯誤、私は基本的に以下を、多かれ少なかれ使用します。

protected Point pointOnCircle() { 

    double rads = Math.toRadians(orbitAngle - 180); // Make 0 point out to the right... 
    int fullLength = Math.round((outterRadius)); 

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

    return new Point(xPosy, yPosy); 
} 

残りの部分は、基本的に

は基本的に、これは、ベースGraphicsコンテキストをとる(地球の位置)をそれに変換を適用し、他の二つのコンテキストをオフに作成し、適切な変換の配合自然を扱うためにダウンしていますその追加の変換、地球のための1と月に1つ...

Graphics2D g2d = (Graphics2D) g.create(); 
int yPos = (getHeight() - size)/2; 
// Transform the offset 
g2d.transform(AffineTransform.getTranslateInstance(xPos, yPos)); 

Graphics2D earthG = (Graphics2D) g2d.create(); 
// Rotate around the 0x0 point, this becomes the center point 
earthG.transform(AffineTransform.getRotateInstance(Math.toRadians(angle))); 
// Draw the "earth" around the center point 
earthG.drawRect(-(size/2), -(size/2), size, size); 
earthG.dispose(); 

// Removes the last transformation 
Graphics2D moonG = (Graphics2D) g2d.create();    
// Calclate the point on the circle - based on the outterRadius or 
// distance from the center point of the earth 
Point poc = pointOnCircle(); 
int moonSize = size/2; 
// This is only a visial guide used to show the position of the earth 
//moonG.drawOval(-outterRadius, -outterRadius, outterRadius * 2, outterRadius * 2); 
moonG.fillOval(poc.x - (moonSize/2), poc.y - (moonSize/2), moonSize, moonSize); 
moonG.dispose(); 

g2d.dispose(); 

を適用し、私はあなたが、実行可能な例をあなたの頭を悩まなければならないことどのくらい知っているので...

Orbit

import java.awt.Dimension; 
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.geom.AffineTransform; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 

public class Test { 

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

    public Test() { 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private double angle; 
     private double orbitAngle; 
     private int xPos = 0; 
     private int size = 20; 
     private int outterRadius = size * 2; 
     private int delta = 2; 

     public TestPane() { 
      new Timer(40, new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        xPos += delta; 
        if (xPos + size >= getWidth()) { 
         xPos = getWidth() - size; 
         delta *= -1; 
        } else if (xPos < 0) { 
         xPos = 0; 
         delta *= -1; 
        } 
        angle += 4; 
        orbitAngle -= 2; 
        repaint(); 
       } 
      }).start(); 
     } 

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

     protected Point pointOnCircle() { 

      double rads = Math.toRadians(orbitAngle - 180); // Make 0 point out to the right... 
      int fullLength = Math.round((outterRadius)); 

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

      return new Point(xPosy, yPosy); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int yPos = (getHeight() - size)/2; 
      // Transform the offset 
      g2d.transform(AffineTransform.getTranslateInstance(xPos, yPos)); 

      Graphics2D earthG = (Graphics2D) g2d.create(); 
      // Rotate around the 0x0 point, this becomes the center point 
      earthG.transform(AffineTransform.getRotateInstance(Math.toRadians(angle))); 
      // Draw the "earth" around the center point 
      earthG.drawRect(-(size/2), -(size/2), size, size); 
      earthG.dispose(); 

      // Removes the last transformation 
      Graphics2D moonG = (Graphics2D) g2d.create();    
      // Calclate the point on the circle - based on the outterRadius or 
      // distance from the center point of the earth 
      Point poc = pointOnCircle(); 
      int moonSize = size/2; 
      // This is only a visial guide used to show the position of the earth 
      //moonG.drawOval(-outterRadius, -outterRadius, outterRadius * 2, outterRadius * 2); 
      moonG.fillOval(poc.x - (moonSize/2), poc.y - (moonSize/2), moonSize, moonSize); 
      moonG.dispose(); 

      g2d.dispose(); 
     } 

    } 

} 

これは、1つの方向に回転している「地球」オブジェクトを移動した後、その周り月を回転し、反対方向

+0

ありがとう。あなたの例はとても助けになります。こうして、簡単です。 – horse9irl

0

では、トランスフォームを連結して、計算を簡素化することができ。最後のトランスフォームから最初のトランスフォームに戻って作業するか、preConcatenateを使用してより自然な順序で構築してください。

変換から変換軌道や回転を構築することにより、例えば、単純な変換からの複雑な変換を、作曲:

// Earth transform. 
// Set the orbital radius to 1/3rd the panel width 
AffineTransform earthTx = AffineTransform.getTranslateInstance(getWidth()/3, 0); 
// Rotate 
earthTx.preConcatenate(AffineTransform.getRotateInstance(angle)); 

その後変換(地球を周回例えば月)は、その後、以前の上に構築することができます結果:

// Moon transform. 
// Set the orbital radius to 1/10th the panel width 
AffineTransform moonTx = AffineTransform.getTranslateInstance(getWidth()/10, 0); 
// Rotate 
moonTx.preConcatenate(AffineTransform.getRotateInstance(angle)); 
// Add the earth transform 
moonTx.preConcatenate(earthTx); 

全例:

public class Orbit { 

    public static class OrbitPanel extends JComponent { 
     int width; 
     int height; 

     public OrbitPanel(int width, int height) { 
      this.width = width; 
      this.height = height; 
     } 

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

     @Override 
     public void paint(Graphics g) { 
      Graphics2D g2 = (Graphics2D) g; 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

      // Clear the background. 
      g2.setColor(getBackground()); 
      g2.fillRect(0, 0, getWidth(), getHeight()); 

      // Sun transform. Just centre it in the window. 
      AffineTransform sunTx = AffineTransform.getTranslateInstance(getWidth()/2, getHeight()/2); 

      // Draw the sun 
      g2.setTransform(sunTx); 
      drawBody(g2, 30, Color.YELLOW); 

      // Orbital period. 
      // One rotation every 10s. 
      double percentRotation = System.currentTimeMillis() % 10000/10000.0; 
      // To radians. 
      double angle = Math.PI * 2 * percentRotation; 

      // Earth transform. 
      // Set the orbital radius to 1/3rd the panel width 
      AffineTransform earthTx = AffineTransform.getTranslateInstance(getWidth()/3, 0); 
      // Rotate 
      earthTx.preConcatenate(AffineTransform.getRotateInstance(angle)); 
      // Add the sun transform 
      earthTx.preConcatenate(sunTx); 

      // Draw the earth 
      g2.setTransform(earthTx); 
      drawBody(g2, 10, Color.BLUE); 

      // Moon transform. 
      // Set the orbital radius to 1/10th the panel width 
      AffineTransform moonTx = AffineTransform.getTranslateInstance(getWidth()/10, 0); 
      // Rotate 
      moonTx.preConcatenate(AffineTransform.getRotateInstance(angle)); 
      // Add the earth transform (already includes the sun transform) 
      moonTx.preConcatenate(earthTx); 

      // Draw the moon 
      g2.setTransform(moonTx); 
      drawBody(g2, 5, Color.DARK_GRAY); 
     } 

     private void drawBody(Graphics2D g2, int size, Color color) { 
      g2.setColor(color); 
      g2.fillOval(-size/2, -size/2, size, size); 
     } 
    } 

    public static void main(String[] args) throws IOException, InterruptedException { 
     JFrame frame = new JFrame("Orbit"); 
     frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
     JComponent orbitPanel = new OrbitPanel(250, 250); 
     frame.add(orbitPanel); 
     frame.pack(); 
     frame.setVisible(true); 

     while (true) { 
      Thread.sleep(20); 
      orbitPanel.repaint(); 
     } 
    } 
} 
+0

それはそんなに役立ちます。ありがとう、トン! – horse9irl

関連する問題