Aufgabe Nr. 2: Astronomie - Unser Sonnensystem

Indi

Member of Honour
Unser Sonnensystem besteht bekanntlich aus einer Sonne und neun Planeten (Merkur, Venus, Erde, Mars, Jupiter, Saturn, Uranus, Neptun, Pluto <-- in der Reihenfolge ausgehend von der Sonne). Denkt euch, diese neun Planeten und die Sonne liegen zu einem bestimmten Zeitpunkt genau in einer Geraden (Es gibt einen bestimmten Begriff für dieses Phänomen. Sollte den jemand wissen, sagt mir bitte bescheid). Dann vergehen viele, viele, viele Jahre und irgendwann passiert es, dass alle neun Planeten und die Sonne wieder in genau einer Geraden liegen. Die Planeten müssen natürlich alle auf einer Seite liegen. Also es gilt nicht, wenn 8 Planeten links auf der Geraden sind, dann die Sonne kommt und dann rechts genau gegenüberliegend auf der anderen Seite der Saturn grad zufällig auf der Geraden liegt. Den Zeitraum zwischen solchen zwei Zeitpunkten nennen wir hier schlicht und einfach "Periode". *g* Soweit die Theorie.

Aufgabe des Programmes:
Programmiere ein Programm, welches erstens die Dauer einer solchen Periode berechnet und ausgibt (Einheit = Erd-Jahre).

Astronomische Daten:

Mittlere Entfernungen der Planeten zur Sonne (in AE=Asronomischen Einheiten):
Merkur: 0,39
Venus: 0,72
Erde: 1
Mars: 1,52
Jupiter: 5,20
Saturn: 9,54
Uranus: 19,20
Neptun: 30,06
Pluto: 39,6

MIttlere Umlaufgeschwindigkeit (in km/s):
Merkur: 47,8
Venus: 35,0
Erde: 29,8
Mars: 24,1
Jupiter: 13,0
Saturn: 9,6
Uranus: 6,8
Neptun: 5,4
Pluto: 4,7

1 A.E. (1 Astronomische Einheit) = 149.600.000 km
Ausbreitung des Lichtes: c = 299.792.458m/s

Mathematischer Hintergrund:
Berechnung des Kreisumfanges: Kreisumfang = Kreisradius * 2 * Pi
Pi = 3,141592654

Das Programm ist vom programmiertechnischen eigentlich nicht wirklich allzu schwer zu coden. Man muss nur bissl nachdenken können. ;)

Ich hab noch absolut keine Ahnung wielang ein normaler PC braucht um sowas zu berechnen. Mir is die Idee der Aufgabe heut im Laufe des Tages mal eingefallen. Ich denk das is auf jeden Fall mal ein interessantes Beispiel. Wünsch euch viel Spaß beim Coden! :)) Aja, umso genauer das Ergebnis umso besser natürlich. Aber bitte verwendet die oben angegebenen Daten, so haben wir beim richtigen Algorithmus auf jeden Fall keine groben Abweichungen.
 
bitte Indi enttäusch mich nicht, aber willst du als Einheit für die ZEIT wirklich Lichtjahre? ;) :D

Wie Magneto in X-Men sagt: "Lernt ihr denn gar nichts in eurer Schule?"
 
Hm, schlag eine alternative Zeitangabe vor, dann pack ich die auch noch der Aufgabenstellung hinzu. :))
 
also nur zur Erklärung: Lichtjahr ist eine Längeneinheit und gibt den Weg an, den das Licht in einem Jahr zurücklegt

Ich bin mir über die Zeiteinheit noch nicht sicher, weil sie entscheidend ist:
wenn man sie zu grob wählt entgeht einem evtl., wenn mehrere Planeten auf einer Geraden stehen (weil sie sozusagen am richtigen Zeitpunkt "vorbeispringen"), wenn man sie zu klein wählt werdeb die Zahllen dafür zu groß, ich denke Stunden sind vielleicht nicht schlecht, werd mal etwas rumprobieren.
Weiterhin ist die Frage, wie genau man die Berechnungen anstellt, mal sehen vielleicht kriege ich ja eine Lösung zustande.

ich hoffe die andern hier machen sich auch mal darüber Gedanken.

Ich hoffe ich sehe das nicht zu kompliziert und es gibt eigentlich ne total einfache Lösung, aber ich glaube nicht.
 
Also nur noch mal zur Erklärung bzgl. dem Forum. Es muss natürlich nicht gleich ein vollständiger Code gepostet werden. Wenn bei bestimmten Teilen Probleme auftreten bzw. erst die Programmstruktur geklärt werden muss, so kann man das natürlich auch hier machen.

@Nornagest: Also ich probier auf jeden Fall schon rum. :))

Bzw. Nachtrag: Ich denke dass Stunden viel zu klein sind.
 
stimmt schon, Stunden sind eine sehr kleine Einheit, aber man muss beachten wie unterschiedlich sich die Planeten bewegen.
Merkur bewegt sich am Tag um 4° während Pluto sich nur um 0.000 irgendwass Grad bewegt.
Das heißt, wenn man Tage als einheit nimmt, wird man schon sehr ungenau (werd ich wahrscheinlich machen).
Außerdem muss man eben die Genauigkeit für die Vergleiche entsprechend festlegen (wie wir alle wissen sollte man Fließkommmazahlen nicht mit == vergleichen :))
naja mal sehen ob ich zu einem Ergebnis komme....
 
Ich bin der Meinung man sollte ein paar Zwischenergebnisse für dieses Programm veröffentlichen, damit man zumindest weiß ob man am richtigen Weg ist oder nicht. *g*

Zb. hab ich das ganze jetzt mal nur mit dem Mars und der Erde programmiert. Ausgehend von einer Geraden zwischen Sonne-Erde-Mars, müsste der Mars ca. 3 Mal um die Sonne und noch ca. 50 Grad weiter laufen, bis sich wieder eine solche Gerade ergibt. Kann das jemand bestätigen? :D
 
Also ich hätte jetzt prinzipiell ein fertiges Programm. Auf meinen alten Laptop rechnet der jetzt aber schon einige Zeit. Ich geh dann mal arbeiten. :)) Mal schaun bis wann hier ein Ergebnis vorliegt. Ach ja, der Code is echt nicht schwer zu machen.
 
Anmerkung:
also bei mir stehen Erde und Mars etwa alle 780 Tage in einer Linie, von der Sonne aus .... Was mach ich falsch?

edit: dein Beispiel ist also das dritte Mal bi mir, dass sie so stehen
 
Astronomisch gesehen ist diese Aufgabenstellung Unfug : Planeten bewegen sich auf Ellipsenbahnen. Zweitens ist es nicht möglich, exakte Positionen von Planeten zu berechnen, da sich hier die Potenzierungsfehler bemerkbar machen. Und drittens wird davon ausgegangen, daß kein Mensch die "Superkonjunktion" je erlebt. Also daß wirklich alle Planeten mit ihren Mittelpunkten auf einer Linie liegen.

Das mal am Rande.
 
Denkt euch, diese neun Planeten und die Sonne liegen zu einem bestimmten Zeitpunkt genau in einer Geraden (Es gibt einen bestimmten Begriff für dieses Phänomen. Sollte den jemand wissen, sagt mir bitte bescheid).


"Superkonjunktion" =)

[Edit: Da war wohl jmd. schneller]


Wollte aber nochmal diesen Link hier posten, den ich ganz interessant fand.
 
1. mein Fehler bezüglich Erde und Mars war einfach diee Genauigkeit

2. natürlich ist die Aufgabe nicht exakt, aber es ist eine Aufgabe
als Ausgangspunkt nehmen wir eben für die Planetenbahnen Kreise und für ihre Bewegung eine gleichförmige Geschwindigkeit an
 
die simpelste lösung ist folgende:
wenn man die umlaufzeiten der planeten in ganzen zahlen (z:B. tage) nimmt, kann man ohne weiteres ihr kleinstes gemeinsames vielfaches bilden. das wäre dann die superkonjunktion an der gleichen stelle. problem ist nur, das man damit keine möglichkeit hat, sie an einer anderen stelle zu finden.
 
@blueflash: Ist prinzipiell eine nette Idee, du versäumst aber mit Sicherheit einige Superkonjunktionen die zwischen dieser Zeitspanne stattgefunden haben.

@Damien: Ich danke dir ja für deine Hinweise, aber wir befinden uns hier nun mal nicht im Astrononime-Unterricht sondern auf einem Computer-Forum. Dass Planeten sich nicht exakt auf Kreisbahnen bewegen, wissen denke ich mal die meisten hier. Und dass hier keiner von uns eine Superkonjunktion je erlebt ist für die Lösung der Aufgabe nicht von Relevanz.

Und damit ist wieder Schluß mit Off-Topic.
 
So, also ich hab das mal geschrieben:

Code:
program Sonnensystem;
uses crt;
var M:array[1..9,1..3] of real; { 0 }
    i,z:integer;
    t:real;

procedure DatenFuellen;
var i:integer;
begin
  {Radien}
  M[1,1]:=0.39;
  M[2,1]:=0.72;
  M[3,1]:=1;
  M[4,1]:=1.52;
  M[5,1]:=5.2;
  M[6,1]:=9.54;
  M[7,1]:=19.2;
  M[8,1]:=30.06;
  M[9,1]:=39.6;
  for i:=1 to 9 do
    M[i,1]:=M[i,1]*149600000;

  {Geschwindigkeiten}
  M[1,2]:=47.8;
  M[2,2]:=35;
  M[3,2]:=29.8;
  M[4,2]:=24.1;
  M[5,2]:=13;
  M[6,2]:=9.6;
  M[7,2]:=6.8;
  M[8,2]:=5.4;
  M[9,2]:=4.7;

end;

function P(planet:integer; t:real):real; { 4 }
var s,U,a:real;
begin
  s:=M[planet,2]*t;
  U:=2*Pi*M[planet,1];
  while s>U do s:=s-U;
  a:=s*360/(2*Pi*M[planet,1]);
  a:=round(a);
  P:=a;
end;


begin
  clrscr;
  writeln('Dieses Programm berechnet die Periodendauer zwischen');
  writeln('zwei Zeitpunkten, an denen alle Planeten des Sonnensystems');
  writeln('in einer Geraden auf einer Seite der Sonne stehen.');
  writeln('Dies kann durchaus mehrere Stunden dauern...');
  writeln;
  writeln('Starten des Programs mit [Enter].');
  readln();

  DatenFuellen;
  t:=25000; { 1 }
  z:=0;  { 2 }

  repeat

    {Drehanzeige}
    if z<4 then inc(z) else z:=0;
    if z=0 then begin clrscr; write('|'); end;
    if z=1 then begin clrscr; write('\'); end;
    if z=2 then begin clrscr; write('-'); end;
    if z=3 then begin clrscr; write('/'); end;
    {/Drehanzeige}

    writeln('  Zeit: ',t,' Sekunden');
    t:=t+25000; { 3 }

  until (P(1,t)=P(2,t)) and (P(2,t)=P(3,t)) and (P(3,t)=P(4,t)) and (P(4,t)=P(5,t)) and (P(5,t)=P(6,t)) and (P(6,t)=P(7,t)) and (P(7,t)=P(8,t)) and (P(8,t)=P(9,t));

  writeln('Periode berechnet.');
  writeln('Periode: ',t);
  readln;
end.

Ist in Pascal. Das Programm berechnet die Positionen der Planeten in abhängigkeit von der Zeit in Grad (gerundet auf 1 Grad) im Abstand von 25000 Sekunden. Solange braucht meiner Berechnung nach Merkur für 1 Grad.
Ich habe das Programm gerade am laufen. Mein Prozessor hat 1,7 GHz und ich habe dem Programm maximale Priorität zugeteilt. Allerdings ist er jetzt (*aufdieuhrguck* schon eine stunde beschäftigt und erst bei 10 hoch 10 Sekunden angekommen...).

Anmerkung: Bin noch Coding-Anfänger und hoffe, ihr lacht Euch net gleich kaputt :D
 
manno langsam hab ich die Lust etwas verloren :)

hier mal mein Proggi in C++:

Code:
#include <iostream>
#include <string>
#include <fstream>
#include <ctime>

const double PI			=3.14159265;
const double GENAUIGKEIT=1.0;							//Genauigkeit der Vergleiche und Berechnungsschritte
const double ENDE		=1000000000.0;					//berechneter Zeitraum
const double JAHR		=3600.0 * 24.0 * 365.0;
const double AE			=149600000.0;

struct Planet
{
	std::string Name;
	double Entfernung;
	double Geschwindigkeit;
	double Umlaufbahn;
};

Planet planet[9];
std::ofstream ausgabe;

inline bool eq(double x, double y)
{
	double tmp=x-y;
	if(tmp<0)
		tmp=-tmp;
	return tmp<GENAUIGKEIT;
}

bool Vergleich(double* Winkel)
{
	bool erg=false;
	for(int i=0;i<9;++i)
		for(int j=i+1;j<9;++j)
		{
			if(eq(Winkel[i], Winkel[j]) && i!=j)
			{
				erg=true;
				ausgabe<<planet[i].Name<<\" und \"<<planet[j].Name<<\"\n\";
			}
		}
	return erg;
}

bool VergleichAlle(double* Winkel)
{
	return (eq(Winkel[0],Winkel[1]) 
		&& eq(Winkel[1],Winkel[2])
		&& eq(Winkel[2],Winkel[3]) 
		&& eq(Winkel[3],Winkel[4])
		&& eq(Winkel[4],Winkel[5]) 
		&& eq(Winkel[5],Winkel[6])
		&& eq(Winkel[6],Winkel[7])
		&& eq(Winkel[7],Winkel[8])
		&& eq(Winkel[8],Winkel[0]));
}

void Werte()
{
	planet[0].Name					=\"Merkur\";
	planet[0].Entfernung			=0.39 * AE;
	planet[0].Geschwindigkeit		=47.8;
	planet[0].Umlaufbahn			=2*PI*planet[0].Entfernung;

	planet[1].Name					=\"Venus\";
	planet[1].Entfernung			=0.72 * AE;
	planet[1].Geschwindigkeit		=35.0;
	planet[1].Umlaufbahn			=2*PI*planet[1].Entfernung;

	planet[2].Name					=\"Erde\";
	planet[2].Entfernung			=1.0 * AE;
	planet[2].Geschwindigkeit		=29.8;
	planet[2].Umlaufbahn			=2*PI*planet[2].Entfernung;

	planet[3].Name					=\"Mars\";
	planet[3].Entfernung			=1.52 * AE;
	planet[3].Geschwindigkeit		=24.1;
	planet[3].Umlaufbahn			=2*PI*planet[3].Entfernung;

	planet[4].Name					=\"Jupiter\";
	planet[4].Entfernung			=5.2 * AE;
	planet[4].Geschwindigkeit		=13.0;
	planet[4].Umlaufbahn			=2*PI*planet[4].Entfernung;

	planet[5].Name					=\"Saturn\";
	planet[5].Entfernung			=9.54 * AE;
	planet[5].Geschwindigkeit		=9.6;
	planet[5].Umlaufbahn			=2*PI*planet[5].Entfernung;

	planet[6].Name					=\"Uranus\";
	planet[6].Entfernung			=19.2 * AE;
	planet[6].Geschwindigkeit		=6.8;
	planet[6].Umlaufbahn			=2*PI*planet[6].Entfernung;

	planet[7].Name					=\"Neptun\";
	planet[7].Entfernung			=30.06 * AE;
	planet[7].Geschwindigkeit		=5.4;
	planet[7].Umlaufbahn			=2*PI*planet[7].Entfernung;

	planet[8].Name					=\"Pluto\";
	planet[8].Entfernung			=39.6 * AE;
	planet[8].Geschwindigkeit		=4.7;
	planet[8].Umlaufbahn			=2*PI*planet[8].Entfernung;
	
}

int main()
{
	clock_t start=clock();
	ausgabe.open(\"planeten.txt\", std::ios_base::out);
	Werte();
	double ZEIT=GENAUIGKEIT * (planet[0].Umlaufbahn / (360* planet[0].Geschwindigkeit));
	double winkel[9]={0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
	double zeit;

	ausgabe<<\"Zeiteinheit: \"<<ZEIT<<\" Sekunden\nGenauigkeit in Grad: \"<<GENAUIGKEIT<<\"\nZeitraum: \"<<ENDE<<\" Jahre\n\n\";
	std::cout<<\"Zeiteinheit: \"<<ZEIT<<\" Sekunden\nGenauigkeit in Grad: \"<<GENAUIGKEIT<<\"\nZeitraum: \"<<ENDE<<\" Jahre\n\n\";

	double dwinkel[9];
	for(int i=0;i<9;++i)
		dwinkel[i]=planet[i].Geschwindigkeit*ZEIT / planet[i].Umlaufbahn *360;

	double tmpJahr;
	for(zeit=1.0;;zeit+=1.0)
	{
		tmpJahr=(zeit*ZEIT) / JAHR;
		for(int i=0;i<9;++i)
		{
			winkel[i]+=dwinkel[i];
			if(winkel[i]>360.0)
				winkel[i]-=360.0;
		}
		if(VergleichAlle(&winkel[0]) && zeit>10)
			break;
		if(tmpJahr > ENDE)
		{
			ausgabe<<\"\nZu lange!\n\";
			clock_t ende=clock();
			ausgabe<<\"Laufzeit(in ms): \"<<ende-start<<\"\n\";
			ausgabe.close();
			return 0;
		}
		/*if(Vergleich(&winkel[0]))								//Kommentare entfernen für alle Konhunktionen
			ausgabe<<\"Nach \"<<static_cast<unsigned long>(zeit*ZEIT)<<\" Sekunden = \"<<(zeit*ZEIT) /(3600*24)<<\" Tagen = \"<<(zeit*ZEIT) /JAHR<<\" Jahre\n\n\";*/
	}
	ausgabe.close();
	ausgabe.open(\"ergebnis.txt\", std::ios_base::out);
	ausgabe<<\"\nNach \"<<static_cast<unsigned long>(zeit*ZEIT)<<\" Sekunden = \"<<zeit*ZEIT /(3600*24)<<\" Tagen = \"<<(zeit*ZEIT) /JAHR<<\" Jahre ist eine Periode vergangen\n\";
	for(i=0;i<9;++i)
	{
		ausgabe<<\"Winkel: \"<<winkel[i]<<\"\n\";
		ausgabe<<\"Gesamt überstrichener Winkel: \"<<planet[i].Geschwindigkeit*static_cast<double>(zeit)*static_cast<double>(ZEIT) / planet[i].Umlaufbahn *360<<\"\n\";
	}
	clock_t ende=clock();
	ausgabe<<\"Laufzeit(in ms): \"<<ende-start<<\"\n\";
	ausgabe.close();
	return 0;
}

der Code sollte soweit verständlich sein, wie die Kommentare zeigen, kann man mit den Konstanten am Anfang die Genauigkeit der Berechnungen (in Grad) und den untersuchten Zeitraum (in Jahren) an.

Wenn jemand Fehler o.ä. findet möge er das bitte schreiben. Das Proggi lief seit Sonntag bis gestern bei mir (Zeitraum 1Mrd Jahre) und brachte keine Ergebnisse. :(
 
Code:
uses crt;

   type tPlanet         = record
            weg         : real;
            grad        : real;
            distanz     : real;
            bahn        : real;
            speed       : real;
            graddistanz : real;
            gradzeit    : real;
            wegprozeit  : real;
   end;


     const
         PSpeed : array[1..9] of real             = ( 47.8, 35, 29.8, 24.1, 13, 9.6, 6.8, 5.4, 4.7 );
         PDistanz         : array[1..9] of real   = ( 0.39, 0.72, 1, 1.52, 5.20, 9.54, 19.20, 30.06, 39.6 );
         AE               : real                  =   149600000;
         Pi               : real                  =   3.141592654;
         TruncFix          : real                  =   0.000000000001;

     var
            
        Gradteiler     : real;
        Sonnensystem   : array[1..9] of tPlanet;
        kleinsteGradzeit            : real;
        vergangeneZeit        : real;

   procedure init;
     var
       x : byte;
     
     begin
       for x:= 1 to 9 do Sonnensystem[x].grad:=0;
       for x:= 1 to 9 do Sonnensystem[x].weg:=0;
       for x:= 1 to 9 do Sonnensystem[x].distanz:=PDistanz[x]*AE;
       for x:= 1 to 9 do Sonnensystem[x].speed:=PSpeed[x];

       for x:= 1 to 9 do Sonnensystem[x].bahn:=Sonnensystem[x].distanz*2*Pi;
       for x:= 1 to 9 do Sonnensystem[x].graddistanz:=Sonnensystem[x].bahn/(360*Gradteiler);
       for x:= 1 to 9 do Sonnensystem[x].gradzeit:=Sonnensystem[x].graddistanz/Sonnensystem[x].speed;
       for x:= 1 to 9 do IF x = 1 then kleinsteGradzeit:=Sonnensystem[x].gradzeit else IF
         Sonnensystem[x].gradzeit<kleinsteGradzeit THEN
           kleinsteGradzeit:=Sonnensystem[x].gradzeit;
       for x:=  1 to 9 do Sonnensystem[x].wegprozeit:=Sonnensystem[x].speed*kleinsteGradzeit;
vergangeneZeit:=0;
     end;

    
   procedure TimeSlice;
      var
        x: byte;

      begin
        for x:= 1 to 9 do begin
          Sonnensystem[x].weg:=Sonnensystem[x].weg + Sonnensystem[x].wegprozeit;
          IF Sonnensystem[x].weg>Sonnensystem[x].bahn THEN
             Sonnensystem[x].weg:=Sonnensystem[x].weg-Sonnensystem[x].bahn;
          Sonnensystem[x].grad:=(Sonnensystem[x].weg/Sonnensystem[x].graddistanz);
        end;
        vergangeneZeit:=vergangeneZeit+kleinsteGradzeit;
      end;



  function Konjunktion:BOOLEAN;
      var
        x:byte;

      begin
        Konjunktion:=True;
        for x:=1 to 9 do begin
          IF NOT (TRUNC(sonnensystem[x].grad+TruncFix)=TRUNC(sonnensystem[x+1].grad+TruncFix)) THEN
         begin Konjunktion:= FALSE; break;
           eND;
         end;
         end;



begin
  gradteiler:=1;
  init;
  repeat
     timeslice;
  until konjunktion;
clrscr;
write('Vergangene Zeit : ', vergangeneZeit,' Sekunden.');
readkey;
end.
 
:(

ich will euch superhirne ja nicht enttäuschen, aber wenn ich in physik aufgepasst hab, dann bewegen sich die planeten in eliptischen bahnen um die sonne.weiters sind sie in sonnennähe schneller...das heißt was ihr hier berechnet, mag vielleicht ne gute übung sein, hat mit der realität aber rein gar nix zu tun...

nur mal so damit ich auch was gesagt hab :)
 
Zurück
Oben