# Sonnensystem Programmieren



## Stimpy21994 (24. Nov 2012)

Hallo liebe Community 

Ich hab ein paar Probleme....
Ich muss für die Schule ein Sonnensystem Programmieren,mit dem ich schriftlich beschreibe wie ich es modelliere und wie ich es Algorithmiere...
So könntet ihr mir sagen ob sowas sehr schwer ist, mit was ich dies am besten programmiere und helft mir einfach!
Danke im vorraus! 
Mfg Stimpy


----------



## träät (24. Nov 2012)

ich hätte jetzt erlich gesgt nicht mal ne idee wie ich anfangen würde ein "sonnensystem" in java zu implementieren ... verstehe daher die frage irgendwie nicht


----------



## BRoll (24. Nov 2012)

Gehts jetzt um die Physik, ein spezielles Sonnensystem,
oder eines generieren?
Muss es grafisch dargestellt werden, oder wie meinst das mit dem Beschreiben.

So kann die Aufagebnstellung sicher nicht sein, da weiß keiner was man machen muss...?


----------



## Marco13 (24. Nov 2012)

```
class Sonnensystem
{
    // Hier dein Code
}
```
Viel mehr kann man bisher nicht sagen.


----------



## Kababär (24. Nov 2012)

Du weißt ja was ein Sonnensystem ist?

Es gibt verschiedene Arten, ein Sonnensystem darzustellen.
Entweder du erstellst für jeden Planeten einen Punkt x (Sonne, x1-x8) mit dem jeweiligen Abstand zum anderen Planeten und der Rotationsgeschwindigkeit um die Sonne. 
Die Sonne gilt hierbei als Ankerpunkt, ist ja klar.
Damit kann man ganz viel machen... sei doch mal kreativ. (Sofern es um kreative Arbeit geht, wenn nicht, dann musst du schon die konkrete Aufgabe angeben  )

Dem ganzen Programm könnte man ein Steckbrief für jeden Planet hinzufügen, sodass, wenn man über einen Punkt x kommt, sich ein kleines Pop-Up-Fenster öffnet (Steckbrief).
Darüber hinaus kann man Zukunftsrechnungen machen, z.B. nächste Sonnenfinsternis, die nächste Sandwolkenbildung auf dem Mars, ... ?

Oder eine Ausgabe nach der Größe der Planeten, nach der Beschaffenheit (terrestrische oder Gasplaneten?), Milchstraße, ... 

Du musst ja nicht alles in dein Programm reinpacken. Das wäre auch etwas "übertrieben".
Nur nachdenken musst du selbst.

mfG


----------



## Stimpy21994 (24. Nov 2012)

Mein genaues Thema lautet "Informatische Modellierung unseres Sonnensystems und Implementierung der Planetenbewegung in Java".
Die Idee wie Kababär habe ich auch  aber ich hab keine Ahnung wie ich diese umsetzen soll. Also vom Programmiertechnischen....


----------



## Marcinek (25. Nov 2012)

Hallo,
ich würde im einfachsten Fall Kreise auf einem Canvas zeichnen.

Gruß,

Martin


----------



## Bernd Hohmann (25. Nov 2012)

Es gibt sowas schon in Form des viel genutzten "OrbitViewers".

Mang's Bat Page: Orbits: Intro to NASA's Orbit Simulator - solar system small body tour

Der Sourcecode ist hier: OrbitViewer (english)

Damit hast Du schonmal eine Grundlage (im Source ist auch die Berechnung der Keplerellipse dabei).

Bernd


----------



## Stimpy21994 (27. Nov 2012)

Danke schonmal  ich mach mich mal daran und werde statusmeldungen geben


----------



## Stimpy21994 (29. Nov 2012)

So ich bins wieder 
ich habe 2 Fragen:
Meine erste wäre warum es mir nur die Sonne anzeigt?
Meine zweite wäre dann wie ich dort bewegung ins spiel kriege?


```
package package1;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;

import javax.xml.transform.Source;

public class MyFirstCanvas extends Canvas  {

	private static final long serialVersionUID = 1L;

	public void paint(final Graphics Sonne){
		super.paint(Sonne);
		Sonne.setColor(Color.yellow);
		Sonne.fillOval(475, 275, 100, 100);
	}

		private void paint1(final Graphics Erde){
			
			super.paint(Erde);
			Erde.setColor((Color.blue));
			Erde.fillOval(600, 300, 50, 50);
		}
		
		public void paint2(final Graphics Merkur){
			super.paint(Merkur);
			Merkur.setColor((Color.PINK));
			Merkur.fillOval(1000, 300, 100, 100);
		}
}
```


----------



## D4rkscr43m (29. Nov 2012)

vielleicht weil paint1 und paint2 nicht aufgerufen werden? :bloed:


----------



## Tobse (29. Nov 2012)

Also hier gleich mit dem Canvas anzufangen halte ich für stark übertrieben. Du solltest erstmal die Planeten da reinmachen. Ich würde hiermit beginnen:

```
class MDPoint
{
	public long posX;
	public long posY;
	public long posZ;
}
class Planet
{
	private MDPoint location = null;
	private int radius = 15;
	private int rotationRadius = 0;
	private int rotationSpeed = 0;
	private String name = "Sonne";
	
	public Planet(MDPoint location, int radius)
	{
		this.location = location;
		this.radius = radius;
	}
	
	// alle möglichen Getter und Setter...
	
	// vllt methoden zum prüfen, ob ein Punkt (X|Y|Z) auf/im Planeten liegt
	
	// methoden zum berechnen der Position auf der Kreisbahn zum zeitpunk t
}
```


----------



## Stimpy21994 (29. Nov 2012)

Tobse hat gesagt.:


> Also hier gleich mit dem Canvas anzufangen halte ich für stark übertrieben. Du solltest erstmal die Planeten da reinmachen. Ich würde hiermit beginnen:
> 
> 
> ```
> ...


Kannst du mir deinen Vorschlag erklären???


----------



## Tobse (29. Nov 2012)

Du solltest jeden Planeten als Klasse implementieren. Dann kannst du in der Klasse mit den Werten sämtliche Nötigen Berechnungen durchführen, z.B. Lage im Sonnensystem zum Zeitpunkt [c]t[/c] oder ob zwei Planeten auf einer Linie liegen (ergo Mond-/Sonnenfinsternis)

Beispiel für die Methode, ob ein Punkt (Hier die Klasse MDPoint) auf dem Planeten liegt:

```
public boolean contains(MPoint p)
{
    // benötigt wird der Vektor vom Planeten-Mittelpunkt zum Punkt p
    // ist die Länge des Vektors <= dem Planetenradius => true
    long vectV1 = p.posX - this.location.posX;
    long vectV2 = p.posY - this.location.posY;
    long vectV3 = p.posZ - this.location.posZ;
    
    // Die Vektorlänge mit dem Satz des Pythagoras errechnen:
    long vectorLength = Math.sqrt(vectV1 * vectV1 + vectV2 * vectV2 + vectV3 * vectV3);
    return vectorLength <= (long) this.radius;
}
```


----------



## Stimpy21994 (1. Dez 2012)

Soweit so gut  
Aber wie zeichnet es die jetzt?
bei mir kommt halt nur das Fenster mit dem Titel Sonnensystem und sonstz alles grau..

```
package package1;

public class MDPoint {
	public long posX;
	public long posY;
	public long posZ;
	
}
class Planet
{
	private MDPoint location = null;
	private int radius =15;
	private int rotationRadius = 5;
	private int rotationSpeed = 2;
	private String name = "Sonne";
	
	
	public Planet(MDPoint location, int  radius)
	{
		this.setLocation(location);
		this.setRadius(radius);
		
	}
	public boolean contains(MDPoint p)
	{

	    long vectV1 = p.posX - this.location.posX;
	    long vectV2 = p.posY - this.location.posY;
	    long vectV3 = p.posZ - this.location.posZ;
	    

	    double vectorLength = Math.sqrt(vectV1 * vectV1 + vectV2 * vectV2 + vectV3 * vectV3);
	    return vectorLength <= (long) this.radius;
	}

	public void setLocation(MDPoint location) {
		this.location = location;
	}

	public MDPoint getLocation() {
		return location;
	}

	public void setRadius(int radius) {
		this.radius = radius;
	}

	public int getRadius() {
		return radius;
	}

	public void setRotationRadius(int rotationRadius) {
		this.rotationRadius = rotationRadius;
	}

	public int getRotationRadius() {
		return rotationRadius;
	}

	public void setRotationSpeed(int rotationSpeed) {
		this.rotationSpeed = rotationSpeed;
	}

	public int getRotationSpeed() {
		return rotationSpeed;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

}
```


```
package package1;

import java.awt.BorderLayout;
import javax.swing.JFrame;
import package1.MDPoint;

public class GUI1
{
		
	
	
	JFrame frame0ne;
	JFrame mainFrame  = new JFrame("Sonnensystem");
	MDPoint Planet = new MDPoint();

	public static void main(String[]args){
		GUI1 verweiß = new GUI1();
		verweiß.createWindow();
	}
	
	public GUI1()
	{
		mainFrame.setLayout(new BorderLayout(20, 20));

		mainFrame.setSize(1024, 800);
		mainFrame.setVisible(true);
			}
	private void createWindow()
	{
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setLayout(null);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.setResizable(false);
		mainFrame.setVisible(true);
		}

		
	}
```


----------



## JohannisderKaeufer (1. Dez 2012)

Erst vor ein paar Tagen habe ich ein kleines Snippet geschrieben

http://www.java-forum.org/java-basics-anfaenger-themen/144495-2d-grafik-zeichnen.html#post963997

Dort geht es um einen "Satelliten", der sich in auf einer Ellipse um einen punkt dreht.


Kannst es dir ja mal anschauen, ob dir sowas vorschwebt und dich bei Fragen nochmal melden.

Daraus ein Sonnensystem zu Basteln sollte nicht allzuschwer sein.


----------



## Stimpy21994 (1. Dez 2012)

JohannisderKaeufer hat gesagt.:


> Erst vor ein paar Tagen habe ich ein kleines Snippet geschrieben
> 
> http://www.java-forum.org/java-basics-anfaenger-themen/144495-2d-grafik-zeichnen.html#post963997
> 
> ...



Danke dafür 

Kannst du oder jmd anders mir sagen was falsch ist?
Also das es nur die "Erde" anzeigt? und warum diese schwarz ist?

```
package package1;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
 
public class Erde {
 
    public Erde() {
        JFrame frame = new JFrame("Sonnensystem");
 
        final ErdePanel Erde = new ErdePanel();
        Erde.setPreferredSize(new Dimension(1024, 800));
        frame.add(Erde);
    
 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
 
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Erde.updatePosition();
                    try {
                        Thread.sleep(2);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
 
    }
 
    public static void main(String[] args) {
        new Erde();
    }
 
    private static class ErdePanel extends JComponent {
        /**
		 * 
		 */
		private static final long serialVersionUID = 2L;
		/**
         * The satellites lastest Position
         */
        private Point2D position = calculatePosition();
 
        /**
         * Calculates the latest Position and triggers an repaint
         */
        public void updatePosition() {
            position = calculatePosition();
            validate();
            repaint();
        }
 
        private Point2D calculatePosition() {
            double xM = getWidth() / 2;
            double yM = getHeight() / 2;
            double r = Math.min(xM, yM) / 2;
 
            //Alle 10 MS 1 Grad Aenderung
            double gamma = System.currentTimeMillis() / 50;
 
            double x = xM + 1.9 * r * Math.cos(Math.toRadians(gamma));
            double y = yM + r * Math.sin(Math.toRadians(gamma));
 
            return new Point2D.Double(x, y);
        }
 
        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            g2d.fillOval((int) position.getX(), (int) position.getY(), 30, 30);
            g2d.setColor(Color.blue);
        }
    

public class Merkur {
 
   	public Merkur() {
        
   		JFrame frame = new JFrame("Sonnensystem");
        
        final MerkurPanel Merkur = new MerkurPanel();
        Merkur.setPreferredSize(new Dimension(1024, 800));
        frame.add(Merkur);
 
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
 
        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    Merkur.updatePosition();
                    try {
                        Thread.sleep(2);
                    } catch (final InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }
    public void main(final String[]args){
    	new Merkur();
    	
    }
    public  class MerkurPanel extends JComponent{

		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		
		private Point2D position = calculatePosition();
        
		
		protected  void updatePosition() {
            position = calculatePosition();
            validate();
            repaint();
        }
   
        private Point2D calculatePosition() {
            final double xM = getWidth() / 5;
            final double yM = getHeight() / 8;
            final double r = Math.min(xM, yM) / 3; 
            //Alle 10 MS 1 Grad Aenderung
            final double gamma = System.currentTimeMillis() / 100;
 
            final double x = xM + 1.9 * r * Math.cos(Math.toRadians(gamma));
            final double y = yM + r * Math.sin(Math.toRadians(gamma));
 
            return new Point2D.Double(x, y);
        }
 
        @Override
        public void paintComponent(final Graphics g) {
            super.paintComponent(g);
            final Graphics2D g2d = (Graphics2D) g;
            g2d.fillOval((int) position.getX(), (int) position.getY(), 30, 30);
        }
    }
}
    }}
```


----------



## JohannisderKaeufer (1. Dez 2012)

Die Erde ist schwarz weil du zuerst Zeichnest (78) und danach die Farbe setzt (79).

Du hast zwei Programme erstellt, eines für die Erde und eines für den Merkur.
Bei einem Sonnensystem sollten allerdings beide Planeten in ein Programm.

Wenn ich das ganze ein wenig umstricke, ein paar Methoden parametrisiere und eine Klasse/Enum für die verschiedenen Parameter der Planeten erstelle dann sieht das so aus.


```
package sonnensystem;

import javax.swing.*;
import java.awt.*;
import java.awt.geom.Point2D;
import java.util.HashMap;
import java.util.Map;

public class Sonnensystem {

    public Sonnensystem() {
        JFrame frame = new JFrame("Sonnensystem");

        final SonnensystemPanel sonnensystemPanel = new SonnensystemPanel();
        sonnensystemPanel.setPreferredSize(new Dimension(1024, 800));
        frame.add(sonnensystemPanel);


        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);

        new Thread(new Runnable() {
            @Override
            public void run() {
                while (true) {
                    sonnensystemPanel.updatePosition();
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();

    }

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

    private static class SonnensystemPanel extends JComponent {

        private Map<Planet, Point2D> positionMap = new HashMap<Planet, Point2D>();

        /**
         * Calculates the latest Position and triggers an repaint
         */
        public void updatePosition() {
            for(Planet planet: Planet.values()){
                positionMap.put(planet, calculatePosition(planet));
            }
            validate();
            repaint();
        }

        private Point2D calculatePosition(Planet planet) {
            double xM = getWidth() / 2;
            double yM = getHeight() / 2;
            double r = planet.getRadius();

            double gamma = System.currentTimeMillis() / (planet.getSpeed() / 360.0 ) ;

            double x = xM + r * Math.cos(-Math.toRadians(gamma));//Minus bedeutet gegen den Uhrzeigersinn
            double y = yM + r * Math.sin(-Math.toRadians(gamma));

            return new Point2D.Double(x, y);
        }

        @Override
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
            for(Planet planet: positionMap.keySet()){
                g2d.setPaint(planet.getColor());
                Point2D position = positionMap.get(planet);
                g2d.fillOval((int) position.getX(), (int) position.getY(), planet.getDurchmesser(), planet.getDurchmesser());
                g2d.setPaint(Color.BLACK);
                g2d.drawString(planet.getName(),(int) position.getX()+planet.getDurchmesser()/2,(int)position.getY());
            }
        }
    }
}
```


```
package sonnensystem;

import java.awt.*;

public enum Planet {
    SONNE("Sonne",Color.YELLOW, 0.0, 40, 1),
    ERDE("Erde",Color.BLUE, 100, 5, 365 * 24 * 60 * 60 * 1000),
    MARS("Mars",Color.GREEN, 120, 10, 12000),
    SATURN("Saturn",Color.darkGray, 300.0, 25, 5000)
    ;
    private final Color color;

    /**Entfernung zum Mittelpunkt des Sonnensystems*/
    private final double radius;
    private final int durchmesser;
    private final int speed;
    private final String name;

    private Planet(String name, Color color, double radius, int durchmesser, int speed) {
        this.color = color;
        this.radius = radius;
        this.durchmesser = durchmesser;
        this.speed = speed;
        this.name = name;

    }
    /**Farbe des Planeten*/
    public Color getColor() {
        return color;
    }
    /**Entfernung zum Sonnenmittelpunkt*/
    public double getRadius() {
        return radius;
    }
    /**Durchmesser des Planeten*/
    public int getDurchmesser(){
        return durchmesser;
    }
    /**Dauer einer Sonnenumrundung*/
    public int getSpeed(){
        return  speed;
    }

    public String getName(){
        return name;
    }
}
```

Die Erde sollte sich einigermassen in Realtime bewegen. Also ein Jahr abwarten und sie ist dann einmal um die Sonne herumgewandert.

Jetzt muß man nur noch die weiteren Planeten-Parameter berechnen und hinzufügen.

Sonnensystem in 131 Zeilen Code (ca. 140 mit allen Planeten)


----------



## Stimpy21994 (2. Dez 2012)

Gut ich habe jetzt alle Planeten 
Meine Frage wäre wie du die Elipse gemacht hast.
Wenn ich beispielweise alle Äquatordurchmesser neme um die Planeten größen zu bestimme und die durch einen bestimmten Faktor teile haut das alles nicht hin...dann kreist der merkur durch die sonne.

So dann wollte ich noch ein paar buttons hinzufügen.
Mein erster wäre das man die Bewegungen von den Planeten einfrieren kann...und wenn man das gemacht hat auf einen planeten klicken kann und einen kleinen Steckbrief auf geht.
Bei dem button muss ich doch nur den Thread unterbrechen?


----------



## JohannisderKaeufer (3. Dez 2012)

Die Elipse bekommt man, indem man indem man mit zwei Variablen (vertikal, horizontal) etwas rumspielt.
[JAVA=65]
double x = xM + vertikal * r * Math.cos(-Math.toRadians(gamma));//Minus bedeutet gegen den Uhrzeigersinn
double y = yM + horizontal * r * Math.sin(-Math.toRadians(gamma));
[/code]

für vertikal == horizontal bekommt man einen Kreis. 

Um das ganze anzuhalten, genügt es den Thread, der das updaten der Position ausführt anzuhalten.
Einen Planeten per click auswählen, kann man mit einem Listener auf dem SonnensystemPanel.
Man muß dann allerdings aufgrund der Position des clicks (x,y-Werte) schauen welcher Planet dazu paßt. Die jeweiligen Punkte der Planeten sind in der positionMap gespeichert.


----------



## Stimpy21994 (3. Dez 2012)

JohannisderKaeufer hat gesagt.:


> Die Elipse bekommt man, indem man indem man mit zwei Variablen (vertikal, horizontal) etwas rumspielt.
> [JAVA=65]
> double x = xM + vertikal * r * Math.cos(-Math.toRadians(gamma));//Minus bedeutet gegen den Uhrzeigersinn
> double y = yM + horizontal * r * Math.sin(-Math.toRadians(gamma));
> ...



Ja das mit der Ellipse ist mir schon klar  aber hast du dir die Formel selber ausgedacht oder gibt es die i-wo? weil im endeffekt muss ich die noch erklären....

Okay dann schau ich mal was sich da machen lässt...ich weiss ich bin anfänger...aber muss ich jetzt für einen button zum beispiel eine neue klasse erstellen oder einfach als unterklasse in die klasse für sonnensystem reinschreiben=?


----------



## JohannisderKaeufer (3. Dez 2012)

Die meisten kennen kartesische Koordinaten - kartesisches Koordinatensystem, dass Punkte oder auch Vektoren mit einem x und y Wert beschreibt.

Dann gibt es noch Polarkoordinaten.
Hierbei werden Punte und Vektoren anhand eines Winkels und einer Länge beschrieben.

Naja, und einen Kreis mit kartesischen Koordinaten zu beschreiben ist IMHO nicht schön.
Mit Polarkoordinaten muß nur eine Länge angegeben werden, der Radius um einen Kreis zu erhalten.


Speziell mit Planeten, die um einen Mittelpunkt kreisen, wird bei Polarkoordinaten nur der Winkel geändert um eine neue Position zu bekommen.

Position(Zeit) = (EntfernungZurMitte, (Zeit modulo ZeitEinerUmrundung) / 360);


Und die Formel ist im Grunde nichts anderes als die Umrechnung von Polarkoordinaten in Kartesische, die Java - Swing zum zeichnen benötigt. Siehe auch Wikipedia.

x = r cos gamma
y = r sin gamma

Minus gamma um eine Drehung entgegen dem Uhrzeigersinn zu bekommen
xM und yM um den Null Punkt zu bekommen um den gedreht werden soll.
Siehe Wikipedia Kreis - Parameterdarstellung.
Die skalare horizontal und vertikal um eine Stauchung, Streckung zur Elipse hin zu bekommen.


IMHO, wenn es um das Drehen von Objekten um einen Winkel geht finde ich sollte man an Polarkoordinaten denken.


----------



## dayaftereh (3. Dez 2012)

Ach so, wenn du es schön machen willst. kannst du bei Wiki Sonnensystem ? Wikipedia die Planeten als PNG holen und mit hilfe von [JAPI]Graphic2D[/JAPI] auf ein Canvas zeichnen. Dabei musst du die Bilder nur als [JAPI]BufferedImage [/JAPI] Laden.


----------

