Aufgabe Nr. 2: Astronomie - Unser Sonnensystem

ich weiß der Thread ist schon sehr alt, aber für Neulinge vielleicht interessant, daß...

Original von TheNeedle
1. bewegen sich planeten nicht auf kreisbahnen (daher Jahreszeiten)

1.5 entstehen Jahreszeiten durch die Neigung der Planetenachse gegen die Ekliptik

Original von TheNeedle
2. sind diese elipsenbahnen gegeneinander geneigt.

2.5 sind die Bahnen im inneren Sonnensystem relativ konstant geneigt (-+ 0.5° - aber sonst hast Du recht.

Der einzige wirkliche Ausreisser ist Pluto (vielleicht wirklich ein eingefangener Planetoid aus der Oort'schen Wolke, wie manche Astronomen glauben) - aber hinter Jupiter sieht den eh kein Aas :)
 
hallo zusammen,

ist zwar schon ne weile her, aber ich finde die Aufgabe hochinteressant.
Dass die astronomische Realität nicht exact wiedergegeben wird stört mich dabei nicht im Geringsten.

Ich habe die bisher geposteten Ergebnisse bisher nur überflogen; natürlich erst, nachdem ich meine Lösung fertig hatte.
Auf den ersten Blick glaube ich, dass mein Lösungsansatz von den bisher geposteten abweicht.
Ich berechne für jeden Tag den zurückgelegten Winkel.
Dann vergleiche ich den Rest, der bei der Division durch 360° (Vollkreis) bleibt.

Würde mich freuen, wenn jemand noch etwas feedback zu meiner Lösung liefern könnte (vor allem ob richtig oder falsch); ich bin nämlich noch ein Anfänger.

Ich lasse auch die erste Konjunktion jedes Planeten mit der Erde ausgeben (als Nebenprodukt).
Falls jemand ein oder mehrere Ergebnis bestätigen oder negieren kann, wäre ich dafür dankbar.
(Die ersten Werte sind aus algebraischen Gründen offensichtlich falsch. Dies könnte man durch Abfragen einer weiteren Bedingung (t >= ein Planetenjahr) ausmerzen, beeinflusst aber nicht das Ergebnis der Hauptaufgabe)

Konjunktion Erde-Venus nach 48 Tagen
Konjunktion Erde-Saturn nach 69 Tagen
Konjunktion Erde-Jupiter nach 86 Tagen
Konjunktion Erde-Merkur nach 183 Tagen
Konjunktion Erde-Neptun nach 189 Tagen
Konjunktion Erde-Pluto nach 432 Tagen
Konjunktion Erde-Mars nach 1049 Tagen
Konjunktion Erde-Uranus nach 1245 Tagen
Runde 1-Million
Runde 2-Million
...
Runde 1072-Million
Runde 1073-Million
Superkonjunktion alle 1073741824 Tage.

Als Endeergebnis erhalte ich 1.073.741.824 Tage.
Dazu benötigte mein Apple G4 Sawtooth 450 Mhz 512 MB RAM 43 Min. 49 Sek.

Interessant finde ich noch, dass sich bei der Umrechnung auf Jahre bei solch astronomischen Werten zwischen 365Tagen pro Jahr und 365,25 Tagen pro Jahre (was immer noch eine grobe Annäherung darstellt) ein Unterschied von über 2000 Jahren ergibt.

Code:
#include<iostream.h>
const double pi = 3.141592654;
const int secProTag = 60*60*60*24;
const int AE = 149000600;
// ************************** Planetendaten **************************
double vMerkur = 47.8*secProTag; 
double rMerkur = 0.39*AE; 
double vVenus = 35.0*secProTag; 
double rVenus = 0.72*AE; 
double vErde = 29.8*secProTag; // in km/d
double rErde = 149000600; // in km
double vMars = 24.1*secProTag; 
double rMars = 1.52*AE; 
double vJupiter = 13.0*secProTag; 
double rJupiter = 5.2*AE; 
double vSaturn = 9.6*secProTag; 
double rSaturn = 9.54*AE; 
double vUranus = 6.8*secProTag; 
double rUranus = 19.2*AE; 
double vNeptun = 5.4*secProTag; 
double rNeptun = 30.06*AE; 
double vPluto = 4.7*secProTag; 
double rPluto = 39.6*AE; 
bool testWinkel(int time);
int Merkur, Venus, Mars, Jupiter, Saturn, Uranus, Neptun, Pluto;
int main()
{
    for(unsigned long t=1;t<4294967295;t++)
    {
        if(t%1000000==0)  // Rundenzähler (jede Millionte Runde)
        {       
            counter++;
            cout << "Runde " << counter << "-Million" << endl;
        }       
        if(testWinkel(t))  // Funktionsaufruf der eigentlichen Testfunktion
        {       
            cout << "Superkonjunktion alle " << t << " Tage." << endl;
            return 0;
        }
    }
    return 0;
}
bool testWinkel(int time)
{
    int winkelMerkur, winkelVenus, winkelErde, winkelMars, winkelJupiter, winkelSaturn, winkelUranus, winkelNeptun, winkelPluto;
    winkelMerkur=(time*180*vMerkur)/(rMerkur*pi);
    winkelVenus=(time*180*vVenus)/(rVenus*pi);
    winkelErde=(time*180*vErde)/(rErde*pi);
    winkelMars=(time*180*vMars)/(rMars*pi);
    winkelJupiter=(time*180*vJupiter)/(rJupiter*pi);
    winkelSaturn=(time*180*vSaturn)/(rSaturn*pi);
    winkelUranus=(time*180*vUranus)/(rUranus*pi);
    winkelNeptun=(time*180*vNeptun)/(rNeptun*pi);
    winkelPluto=(time*180*vPluto)/(rPluto*pi);
    if((winkelErde%360==winkelMerkur%360)  && (winkelErde%360==winkelVenus%360) && (winkelErde%360==winkelMars%360) && (winkelErde%360==winkelJupiter%360) && (winkelErde%360==winkelSaturn%360) && (winkelErde%360==winkelUranus%360) && (winkelErde%360==winkelNeptun%360) && (winkelErde%360==winkelPluto%360))
        return 1;
// ************************** Ab hier ist es Dreingabe **************************
    if((winkelErde%360==winkelMerkur%360) && (Merkur!=1)){Merkur =1;
        cout << "Konjunktion Erde-Merkur nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelVenus%360) && (Venus!=1)){Venus=1;
        cout << "Konjunktion Erde-Venus nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelMars%360) && (Mars!=1)){Mars=1;
        cout << "Konjunktion Erde-Mars nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelJupiter%360) && Jupiter!=1 ){Jupiter=1;
        cout << "Konjunktion Erde-Jupiter nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelSaturn%360) && Saturn!=1){Saturn=1;
        cout << "Konjunktion Erde-Saturn nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelUranus%360) && Uranus!=1){Uranus=1;
        cout << "Konjunktion Erde-Uranus nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelNeptun%360) && Neptun!=1){Neptun=1;
        cout << "Konjunktion Erde-Neptun nach " << time << " Tagen" << endl;}
    if((winkelErde%360==winkelPluto%360) && Pluto!=1){Pluto=1;
        cout << "Konjunktion Erde-Pluto nach " << time << " Tagen" << endl;}
// ************************** Bis hier ist es Dreingabe **************************
    return 0;
}
------
neues post ist mir leider nicht erlaubt, daher diese Ergänzung:
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....
Ganz anders als die Beiträge hinsichtlich der Astronomischen Realität (welche ich für flüssiger als Wasser halte) betrachte ich diesen Beitrag für außerordentlich interessant.
Die Frage nach der zu wählenden Genauigkeit ist nämlich IMHO einer der wesentlichsten Vorüberlegungen.
Dabei ist m. E. nicht nur die Frage nach den betrachteten Zeitintervallen zu stellen, sondern auch die Frage: Mit welcher Abweichung wird eine Konstallation noch als Gerade betrachtet:
Winkelgleichheit mit der Genauigkeit auf ganze Altgrad(habe ich gemacht, Vollkreis=360°), Neugrad (Vollkreis=400), wie in der Astronomie üblich oder gar mehrere Grade, also mathematisch etwas ungenauer, aber irgendwie auch noch "richtig".

Was dann darüber hinaus noch die Genauigkeit der Computerberechnung angeht, bin ich noch völlig unwissend - wenn mir hier jemand ein paar erläuternde Hinweise geben könnte, wäre ich ganz besonders froh.
 
Falls jemand Bedarf an einer einigermaßen korrekten Lösung hat:

Eine Möglichkeit, die Lösung im Rahmen der gegebenen Werte genau zu finden, ist folgende:

Eine geeignete Zeiteinheit für einen Zeitfaktor x wählen.
Errechnen, wieviele Grad seiner Bahn jeder Planet in der Zeit x zurücklegt. (Gi; i=(1..9))

Jetzt kann man die Position der Planeten relativ bequem auf den Einheitskreis abbilden:

x -> (K1i,K2i); wobei

K1i = sin(Gi*x) und K2i = cos(Gi*x)

Damit kann man jetzt ein Gleichungssystem aufstellen, dessen Lösung gleichzeitig auch die Lösung unserer Aufgabe ist.

Alternativ kann man natürlich das ganze auch über eine Abbildung machen, die eine Modulo-Operation benutzt, je nachdem was einem eher liegt. Dies sind nur zwei Möglichkeiten, eine korrekte, beliebig genaue Lösung zu erhalten.

Regards, Ray
 
Hallo Ray, hallo all,

heute ist eine Konjunktion Erde - Venus, wie Ihr sicher mitbekommen habt.
Die letzte war 1882.
Falls hier nicht die Querneigung der Planetenbahnen zueinander auch noch eine Rolle spielt, wäre das ideal zum Überprüfen eines Lösungsansatzes

Original von Damien
Falls jemand Bedarf an einer einigermaßen korrekten Lösung hat:

Eine Möglichkeit, die Lösung im Rahmen der gegebenen Werte genau zu finden, ist folgende:

Eine geeignete Zeiteinheit für einen Zeitfaktor x wählen.
Errechnen, wieviele Grad seiner Bahn jeder Planet in der Zeit x zurücklegt. (Gi; i=(1..9))

Jetzt kann man die Position der Planeten relativ bequem auf den Einheitskreis abbilden:

x -> (K1i,K2i); wobei

K1i = sin(Gi*x) und K2i = cos(Gi*x)

Damit kann man jetzt ein Gleichungssystem aufstellen, dessen Lösung gleichzeitig auch die Lösung unserer Aufgabe ist.
Ja, ja, kann, aber wo ist das Gleichungssystem ? ;)
Da wirds dann nämlich schon wieder nicht mehr ganz so bequem *g*.
Wenn das Prinzip mal steht, dürfte es nicht allzu schwer sein, das in einem Programm zu implementieren.

Original von Damien
Alternativ kann man natürlich das ganze auch über eine Abbildung machen, die eine Modulo-Operation benutzt, je nachdem was einem eher liegt. Dies sind nur zwei Möglichkeiten, eine korrekte, beliebig genaue Lösung zu erhalten.

Regards, Ray
Mit Modulo hab ich das ja gemacht (s. o.) kam mir einfacher vor.
Leider ist die Beteiligung ein bisschen schwach bei dieser Aufgabe; ich hätte gerne mein Ergebnis mit anderen verglichen.
Bei der Lösung mit den Winkelfunktionen muss man sich wahrscheinlich noch mehr Gedanken über eine sinnvolle Rechngenauigkeit machen, da ja hier keine Ganzzahlen als Ergebnis herauskommen.
Wie hast Du Dir das gedacht ?
 
Ich hab' das ganz einfach über Brute-Force und mit frei wählbaren Teilern gemacht (siehe oben), der Ansatz über ein GS ist allerdings genauer (wesentlich) und höchstwahrscheinlich im Endeffekt von Hand schneller umgesetzt. Ich hab' ausserdem nur das Prinzip EINER Lösung vorgestellt. Wenn man faul aber schlau ist, kann man sich auch noch eine injektive Abbildung bauen, die das Ergebnis aus dem R2 in den R1 abbildet, dann sieht's erstmal einfacher aus ^^. Die Lösung mit dem Einheitskreis erscheint mir persönlich besser, da der Modulo ja p.D. das Ergebnis einer Ganzzahldivision ist [...], ergo Genauigkeitsverlust frei Haus dazu kommt. Bei der Abbildung auf den Einheitskreis ist eben dieser frei wählbar. Da kann man nach der 2ten oder nten Stelle abbrechen, das kann man dem geneigten Anwender überlassen.

Ich hab ja auch nicht gesagt, daß das ganze bequem ist. Nur die Abbildung auf den Einheitskreis ist das. :P
 
Gar keins. Ich hab' das nicht praktisch umgesetzt, da ich mich da meist etwas dumm anstelle. Und bei der brute-force-Variante habe ich keine Geduld ^^.
 
Hi @ all,
Ich hab mich als Neuling auch mal mit dem Thema beschäftigt.
Folgendes habe ich auf www.astronews.com gefunden:

In einem Artikel, der im Jahr 1961 in der Zeitschrift Sky & Telescope
erschien, wurden die Daten veröffentlicht, zu denen alle Planeten unseres
Sonnensystems (mit Ausnahme von Pluto) sich von der Sonne aus gesehen in
einem Sektor von weniger als 90 Grad befinden. Der Autor fand 25 Ereignisse
dieser Art in einer Zeitspanne von 0 bis zum Jahr 3000. Am "dichtesten"
standen die Planeten am 11. April 1128 (nach dem Julianischen Kalender)
zusammen - sie passten in einen Sektor von nur 40 Grad.

Oben beschriebene Konstellationen mit allen neun Planeten sind noch
seltener: Das letzte Ereignis dieser Art war am 1. Februar 949 (nach dem
Julianischen Kalender) mit einem Winkel von 80 Grad. Als nächstes - und hier
in einem 90 Grad Sektor - wird dies am 6. Mai 2492 der Fall sein. (ds/19.
Dezember 2003)

Zu Meiner Idee:
Ich hab alle Planetenbahnen auf die größte Aufgeblasen. (also: Faktor:=UmlaufbahnPluto/UmlaufbahnVenus;
vVenus:=vVenus*Faktor // das in mit allen Planeten, die sich mit unterschiedlichen Geschwindigkeiten auf einer
gleichlangen Bahn bewegen.) Müsste sich das jetzt mit einem Gleichungsystem lösen lassen? Die BrutForce Methode
hat mein Rechner lahmgelegt ... . X(
Ich versuchs weiter ...
 
Hallo HexADecimal,

das ist ja sehr interessant.
So kann man seine Ergebnisse wenigstens mal überprüfen.
Hast Du noch den genauen Link zu dem von Dir zitierten Artikel ?

Auch das finde ich sehr interessant:
Venusdurchgänge erfolgen in einem ziemlich regelmäßigen Rhythmus: normalerweise treten sie paarweise in einem Abstand von 8 Jahren auf. Dann dauert es 105,5 Jahre bis zum nächsten Paar und danach weitere 121,5 Jahre, bevor sich der Zyklus wiederholt. Gelegentlich gibt es aber nur einen Durchgang, anstatt eines Paares. So wird dem Transit am 18. Dezember 3089 acht Jahre später kein zweiter folgen. Auch im 14. Jahrhundert gab es nur einen Durchgang.
Das heisst, diese Ereignisse treten als nicht unbedingt ganz regelmäßig auf.
Ich vermute, dass liegt an der Querneigung der Elipsenbahnen.
Wir hatten das ja etwas vereinfacht.
 
Also, ich hab das Prog mal generiert und auf unserem Schulpc gestartet. Ist nur ne 400 MHZ Maschine, aber dafür läuft sie Tag und Nacht :D. Bin gespannt, wann es ein Ergäbniss bringt... Meld mich dann wieder ;)

MfG
Mobius
 
So, ich habe mich vor einiger Zeit mal wieder damit befasst und meinen Code von damals erheblich verbessert:

Sprache: Pascal
Quellcode und Linux i386 Binary: cxmedia.ath.cx/div/superpos/

Das Programm habe ich mal auf meinem 800 MHz-Duron laufen lassen. Nach acht Tagen ist er jetzt bei 7,59*10^8 Jahren und hat noch keine Superposition ausgespuckt. Ein Bekannter an der Uni Freiburg hat es mal auf einem Rechner dort laufen lassen, aber leider konnte er es nicht lange genug rennen lassen.

Vielleicht hat jemand grad zufällig die Möglichkeit, das irgendwo zu starten und es mal machen zu lassen. Wenn das der Fall sein sollte, würde mich das Ergebnis sehr interessieren.

Ich habe Stunden als Einheit gewählt, da bei Merkur eine Stunde schon durchaus eine bedenkliche Bewegung hervorruft.

Natürlich hab ich ein paar physikalische Tatsachen unter den Teppich gefegt: Eliptische Planetenbahnen, Neigung der Bahnen, Reibung, das Ende der Zeit bzw. makroskopische Einflüsse auf das Sonnensystem.

Als genauigkeit für die Superposition habe ich 1 Grad gewählt. Also nur bei <1 Grad handelt es sich um eine.

Code:
program Sonnensystem;
uses crt;
var M:array[1..9,1..3] of real; { Planetendaten (Radien, Geschw., bish. Weg }
    t:real; { Verstrichene Zeit }

procedure DatenFuellen;
{ Füllt die Radien und Geschwindigkeiten ins M-array }
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;

  { Umrechnung von AE in km }
  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;

  { Umrechnung von km/s in °/h }
  for i:=1 to 9 do
  begin
    M[i,2]:=M[i,2]/M[i,1]; { Bogenmass }
    M[i,2]:=M[i,2]*360/(2*Pi); { Gradmass }
    M[i,2]:=M[i,2]*3600*6; { s-->h für "*6" s. Z. 55}
  end;

  { Weg = 0 }
  for i:=1 to 9 do M[i,3]:=0;

end;


procedure mv;
var i:byte;
begin
  for i:=1 to 9 do
  begin
    M[i,3]:=M[i,3]+M[i,2]{*6 s. Zeile 41}; { Positionsänderung in 6h }
    if M[i,3]>360 then M[i,3]:=M[i,3]-360; { Wert unter 360° }
  end;
end;



{ Hauptprogramm }
begin
  clrscr;
  writeln('Superpos 0.4 (19.09.2004)');
  writeln('==========================================================');
  writeln('Autor: Chris (admin@cxmedia.ath.cx)');
  writeln('Pascal-Source: http://cxmedia.ath.cx/div/superpos.pas');
  writeln('Linux i386 Binary: http://cxmedia.ath.cx/div/superpos');
  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('(Genauigkeit 1 Grad)');
  writeln('Dies kann durchaus mehrere Stunden dauern...');
  writeln;
  writeln('Starten des Programs mit [Enter].');
  readln();

  DatenFuellen;
  t:=200; { Startzeit !=0, sonst hält er bei t=0 sofort an ;) }

  repeat
    repeat
      repeat
        repeat
          repeat
            repeat
              repeat
                repeat

                  t:=t+6; { Zeitinkrement }
                  mv;

                until round(M[8,3])=round(M[9,3]);
              until round(M[7,3])=round(M[8,3]);
              writeln(t/(24*365.25),' Jahre');
            until round(M[6,3])=round(M[7,3]);
          until round(M[5,3])=round(M[6,3]);
        until round(M[4,3])=round(M[5,3]);
      until round(M[3,3])=round(M[4,3]);
    until round(M[2,3])=round(M[3,3]);
  until round(M[1,3])=round(M[2,3]);

  writeln('Periode berechnet.');
  writeln('Periode: ',t/(24*365.25), 'Jahre');
  readln;
end.
 
geschafft^^

Sorry, das ich so nen alten Thread wieder nach vorne geholt habe aber... siehe Topic

es sind... 9,27109246373617*10^28 Tage oder 253.972.602.739.726.027.397.260.273 Jahre (rund)

Ich habe ein etwas anderes Verfahren verwendet. Ersteinmal habe ich nicht die Bahngeschwindigkeiten und die Entfernungen genommen, sondern die Periodendauer T in Tagen^-1. Anschließend habe ich alle Planeten in Paaren betrachtet. (Merkur-Venus, Venus-Erde, Erde-Mars, ...) Dann kam ich auf vollgende Ergebnisse (alles in Tagen):

144,512
586,549
778,665000000001
816,509000000001
7245,49899999943
16558,6390000021
62547,5140000276
179690,554000109

Die Kreisbahnen sind ja perfekt (absolut gleichmäßig und unbeschleunigt) Das heißt, jedesmal, wenn zwei Planeten in Reihe stehen, dauerts immer den gleichen Zeitinterval, bis sie das wieder tun. Anschließend muss noch das KgV gebildet werden (kleinste gemeinsame Vielfache) Da fängt das Problem an... und die signifikanten Ziffern auf :( Die Zahl hat 28 Stellen, Extended 19-20 genaue Ziffern, wenn da noch jemannd ne Idee hat, währe gespannt, Primzahlzerlegung oder so :D )

Zur Genauigkeit: Bei jedem Durchlauf wird der Tagezähler um 0.001 erhöht, also 86.4s, . Beim Vergleich wird eine Genauigkeit von 0,01% gefordert. (1 entspricht volle Umdrehung, maximale Abweichung voneinander: 0.0001)

Den Source fürs KgV habe ich geklaut, wenn jemannd ne bessere Idee hat für so große Zahlen... bitte, gernde :D (evtl. Primfaktorenzerlegung oder so)

Die Planeten bekommen auch noch nen Vorsprung 5^i Tagen (ist willkürlich, habs aber durchgetestet). Das ist einfach deshalb, weil bei so kleinen Zeiteinheiten die Bedingung so schon wahr ist... 1.5min sind nicht wirklich viel^^


Jetzt der Source...
Code:
var
  Form1: TForm1;
  UmlaufT:array[0..8] of extended; //  Winkelgeschwindigkeit In Tagen^-1
  UmlProz:array[0..8] of extended; // Prozente vom Umlauf, 2 hätten genügt, stammt aber noch von älteren Versionen...
implementation

{$R *.dfm}

// Suche fürs Planetenpaar
function FindSamePoint(P1,P2:integer; TagStep, Vorsprung:extended):extended;
Var
Tag:extended;
ok:boolean;
Begin
Tag:=Vorsprung;
repeat
  Tag:=Tag+TagStep;

  UmlProz[P1]:=Tag * UmlaufT[P1] - int (Tag * UmlaufT[P1]);  // In Bogenmaß
  UmlProz[P2]:=Tag * UmlaufT[P2] - int (Tag * UmlaufT[P2]);  // In Bogenmaß

  //check-Ok, ich weiß abs() käme cooler
  ok:=((UmlProz[P1]-UmlProz[P2]<0.0001) and (UmlProz[P1]>=UmlProz[P2])) or
      ((UmlProz[P2]-UmlProz[P1]<0.0001) and (UmlProz[P2]>=UmlProz[P1]));
until ok;
result:= Tag;
end;

// geklaut
function ggtReal(a,b:Extended):Extended;
begin
if abs(B) < 0.5 then result:=a
  else result:=ggtReal(b,a-b*int(a/b));
end;

// geklaut
function kgVReal(a, b: extended): extended;
begin
result := a * b / ggTReal(a, b);
end;

procedure TForm1.Button1Click(Sender: TObject);
Var
Tage:array[0..7] of extended;
theKGV:extended;
i:integer;
begin
for i:=0 to 7 do
    Tage[i]:=FindSamePoint(i,i+1,0.001,power(5,i));

theKGV:=1;
for i:=0 to 7 do
  theKGV:=KgVReal(theKGV,Tage[i]);
form1.Memo1.Lines.Add(floattostr(theKgV));

end;

procedure TForm1.FormCreate(Sender: TObject);
begin
UmlaufT[0]:=1/88;
UmlaufT[1]:=1/225;
UmlaufT[2]:=1/365;
UmlaufT[3]:=1/687;
UmlaufT[4]:=1/4329;
UmlaufT[5]:=1/10753;
UmlaufT[6]:=1/30663.65;
UmlaufT[7]:=1/60148;
UmlaufT[8]:=1/90407;
end;

und... eure Meinung?

MfG Zemy
 
Sorry... nicht ganz!

Deinen Ansatz find ich wirklich ziemlich interessant, aber einen kleinen Schönheitsfehler hat er doch:

Du rechnest immer mit den Differenzen zwischen zwei Überlagerungen, dass führt aber nicht zum endgültigen Ergebnis, denn dabei berücksichtigst du nicht die längste Umlaufzeit.

Um zu veranschaulichen, worauf ich hinaus will folgendes Beispiel:
Stell dir eine Uhr vor mit Minuten-, Sekunden- und Stundenzeiger. Damit Sek.- und Min.zeiger sich überschneiden, braucht es 60 sek (nagut, 61 um genau zu sein, aber wir wollen das mal abrunden). Damit sich Std.- und Min.-Zeiger überschneiden braucht es 3600 sek.

Das kgv von diesen beiden Werten ist aber 3600sek und nicht 86400sek.

Davon abgesehen halte ich es für nicht besonders gut das kgv mit Fließkommazahlen auszurechnen. Schon ein minimaler Rundungsfehler x Stellen hinter dem Komma würde das Ergebnis beträchtlich verfälschen!

Greez D.

Wenn ich mal zu viel Zeit hab werd ich auch mal ne Lösung suchen...
 
Das mit Sekunden-Minuten-Stunden-Zeiger stimmt Schon. Sekundne und Minutenzeiger treffen sich alle 60 Sekunden und Minute-Stundnenzeiger alle 3600s Das KGV von 3600 und 60 ist nun mal 3600, denn 60*60=3600 und 1*3600=3600... das liefert auch meine Prozedur... Ein KGV aus Reals funktioniert zugegebener Maßen nicht so gut. man könnte sie in int umwandeln [int (Wert*2)+1, enden ja alle seltsamerweise auf ungefähr 0.5] und da einen genaueren Wert ermitteln. Wie ich allerdings schon beschrieben habe, ist das andere Problem das kein Datentyp in Delphi genug genaue Stellen für diese Zahl hat. Ich habe momentan aucvh keine Zeit, mich darum zu kümmern... (scheiß Facharbeit)

MfG Zemy

[EDIT] so, jetzt hatte ich Zeit :D

Code:
procedure TForm1.Button2Click(Sender: TObject);
Var
  Umlauff:array[0..8] of extended;
  collisions:array[0..7] of int64;
  Prims,tmpPrim:array[0..125000] of integer;
  i,j,divisor:integer;
  rest,specialprims:int64;
  tGes:extended;
  PrimFound:boolean;
begin
   Umlauff[0]:=1/(87.97*24*3600);     // Frequenzen in Hz
   Umlauff[1]:=1/(224.7*24*3600);
   Umlauff[2]:=1/(365.26*24*3600);
   Umlauff[3]:=1/(686.98*24*3600);
   Umlauff[4]:=1/(4331.865*24*3600);
   Umlauff[5]:=1/(10752.9*24*3600);
   Umlauff[6]:=1/(30685.4926*24*3600);
   Umlauff[7]:=1/(60191.1954*24*3600);
   Umlauff[8]:=1/(90406.85*24*3600);


  // Ausgabestuff ...

  // Zeit zwischen 2 Konvergenzen
  // f1*t = f2*t + 1  -> Wenn sich beide Wiedertreffen,
  //                       hat der innere ne Runde mehr
  // Umgestellt: t = 1 / (f1 - f2 )
  for i := 0 to 7 do
    collisions[i]:=trunc(1/(Umlauff[i]-Umlauff[i+1]));

  // Ausgabestuff .... 

  // Primfaktorzerlegung
  ZeroMemory(@Prims,sizeof(Prims)); // Nullsetzen
  specialPrims:=1;

  for i := 0 to 7 do
    begin
      ZeroMemory(@tmpPrim,sizeOf(tmpPrim)); // Nullsetzen
      rest:=collisions[i]; 
      divisor:=1;
      PrimFound:=false;

      repeat
        inc(divisor);
        if divisor>125000 then                // Prims>125000  werden extra erfasst
          begin
            specialprims:=specialprims * rest;
            PrimFound:=true;
          end;

        if rest mod divisor = 0 then // ist ein Teiler 
          begin
            inc(tmpPrim[divisor]);
            rest:=rest div divisor;
            divisor:=1;
          end;
      until (rest=0) or PrimFound;

      for j := 0 to 125000 do
        if Prims[j]<tmpPrim[j] then
          Prims[j]:=tmpPrim[j];
    end;


  // Extrem Multiplying
  tGes:=1*specialPrims;
  for i := 0 to 125000 do
    if Prims[i]<>0 then
      tGes:=tGes * Prims[i];
  // Ausgabestuff....
end;

Und hier die Ausgabe:
T der Konvergenz zweier Planeten in Tagen
Merkur und Venus: 144,568553240741 Tage
Venus und Erde: 583,906666666667 Tage
Erde und Mars: 779,952488425926 Tage
Mars und Jupiter: 816,460486111111 Tage
Jupiter und Saturn: 7254,29952546296 Tage
Saturn und Uranus: 16553,6937384259 Tage
Uranus und Neptun: 62597,9490625 Tage
Neptun und Pluto: 180095,266701389 Tage

T der Konvergenz zweier Planeten in Sekunden
Merkur und Venus: 12490723 Sekunden
Venus und Erde: 50449536 Sekunden
Erde und Mars: 67387895 Sekunden
Mars und Jupiter: 70542186 Sekunden
Jupiter und Saturn: 626771479 Sekunden
Saturn und Uranus: 1430239139 Sekunden
Uranus und Neptun: 5408462799 Sekunden
Neptun und Pluto: 15560231043 Sekunden

********************
kGv : 1,34090900765759E19
tges: 1,34090900765759E19 s
tges: 2,23484834609599E17 min
tges: 3,72474724349332E15 h
tges: 155197801812222 d
tges: 425199457019,785 a

Dummerweise weicht das Ergebnis um 12 Stellen von meinem vorherigen ab :( ist das Normal ??
 
Hab mal über die Feiertage ein Sonnensystem in OpenGL programmiert.
Im Anhang ein Foto wie das ganze aussieht.

solar.cpp
Code:
// Solarsystem (c) 2005 by Tec
// visit: www.tecsoft.de.vu

#include <iostream>
#include <gl\glut.h>
#include "glutcallbacks.h"

int main(int argc, char** argv)
{   
    glutInit(&argc, argv);
    glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH );
    glutInitWindowSize(1024, 768);
    glutInitWindowPosition(100, 100);
    glutCreateWindow("Ein Sonnensystem mit Szenengraph");
    cbacks();
    init();
    glutMainLoop();
    return 0;
}


scenegraph.cpp
Code:
#include "scenegraph.h"

void sceneGraphTraversal(Knoten *root)
{
   if (root == 0) return;

   glPushMatrix();
      glMultMatrixf(root->m);
      if (root->child != 0)
         sceneGraphTraversal(root->child);
      root->draw();
   glPopMatrix();
   if (root->sibling != 0)
         sceneGraphTraversal(root->sibling);
}


scenegraph.h
Code:
#ifndef SCENEGRAPH
#define SCENEGRAPH
#include <gl\glut.h>

typedef struct Knoten {
  GLfloat m[16];  
  void (*draw)(); 
  
  Knoten *sibling; 
  Knoten *child;   
};
  
void sceneGraphTraversal(Knoten *root);
#endif


glutcallbacks.cpp
Code:
#include <iostream>
#include "glutcallbacks.h"
#include "scenegraph.h"
using namespace std;

bool autoplay = true;

Knoten sun, earth, moon, mars, moonMars;

GLfloat sunRadius = 1.0, earthRadius = 0.3, moonRadius = 0.1, marsRadius = 0.2, moonMarsRadius = 0.06;
GLfloat orbit = 5.0, moonOrbit = 0.75, marsOrbit = 7.0, moonMarsOrbit = 0.5;

GLfloat sunColor[3] = {1.0, 1.0, 0.0},
        earthColor[3] = {0.0, 0.0, 1.0},
        moonColor[3] = {0.7, 0.3, 0.0},
        marsColor[3] = {0.4, 0.5, 0.3},
        moonMarsColor[3] = {0.5, 0.3, 0.4};
 
bool bSolid = false;

int incYear = 2, incDay = 12, incMonth = 6;

static int year = 0, day = 0, month = 0; /* Jahr und Tag */

void solarsystem(void)
{
  sun.draw = drawSun;
  sun.sibling = 0; sun.child = &earth;
  moveSun();
  
  earth.draw = drawEarth;
  earth.sibling = &mars; earth.child = &moon;
  moveEarth();

  moon.draw = drawMoon;
  moon.sibling = 0; moon.child = 0;
  moveMoon();

  mars.draw = drawMars;
  mars.sibling = 0; mars.child = &moonMars;
  moveMars();

  moonMars.draw = drawMoonMars;
  moonMars.sibling = 0; moonMars.child = 0;
  moveMoonMars();
}

void drawSun()
{
   glMatrixMode(GL_MODELVIEW);
   glColor3fv(sunColor);
   if(!bSolid)
      glutWireSphere(sunRadius, 20, 16);
   else
      glutSolidSphere(sunRadius, 20, 16);
}

void moveSun()
{
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
      glLoadIdentity();  
      glRotatef(90,1.0,0.0,0.0);
      glGetFloatv(GL_MODELVIEW_MATRIX, sun.m);
   glPopMatrix();
}

void drawEarth()
{
   glColor3fv(earthColor);
   if(!bSolid)
      glutWireSphere(earthRadius, 20, 16);
   else
      glutSolidSphere(earthRadius, 20, 16);
}


void moveEarth(void)
{
   glMatrixMode(GL_MODELVIEW);
   glColor3fv(earthColor);
   glPushMatrix();
      glLoadIdentity();  
      glRotatef(-90,1.0,0.0,0.0);
      glRotatef(year,0.0,1.0,0.0);
      glTranslatef(orbit,0.0,0.0);
      glRotatef(day,0.0,1.0,0.0);
      glRotatef(90,1.0,0.0,0.0);
      glGetFloatv(GL_MODELVIEW_MATRIX, earth.m);
   glPopMatrix();
}

void drawMoon()
{
   glMatrixMode(GL_MODELVIEW);
   glColor3fv(moonColor);      
   if(!bSolid)
      glutWireSphere(moonRadius, 20, 16); 
   else
      glutSolidSphere(moonRadius, 20, 16); 
}

void moveMoon(void)
{      
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
      glLoadIdentity();  
      glRotatef(-90,1.0,0.0,0.0);
      glRotatef(month,0.0,1.0,0.0);
	   glTranslatef(moonOrbit,0.0,0.0);
      glRotatef(90,1.0,0.0,0.0);
      glGetFloatv(GL_MODELVIEW_MATRIX, moon.m);
   glPopMatrix();
}

void drawMars()
{
   glMatrixMode(GL_MODELVIEW);
   glColor3fv(marsColor);      
   if(!bSolid)
      glutWireSphere(marsRadius, 20, 16); 
   else
      glutSolidSphere(marsRadius, 20, 16); 
}

void moveMars(void)
{      
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
      glLoadIdentity();  
      glRotatef(-90,1.0,0.0,0.0);
      glRotatef(month,0.0,1.0,0.0);
	   glTranslatef(marsOrbit,0.0,0.0);
      glRotatef(90,1.0,0.0,0.0);
      glGetFloatv(GL_MODELVIEW_MATRIX, mars.m);
   glPopMatrix();
}

void drawMoonMars()
{
   glMatrixMode(GL_MODELVIEW);
   glColor3fv(moonMarsColor);      
   if(!bSolid)
      glutWireSphere(moonMarsRadius, 20, 16); 
   else
      glutSolidSphere(moonMarsRadius, 20, 16); 
}

void moveMoonMars(void)
{      
   glMatrixMode(GL_MODELVIEW);
   glPushMatrix();
      glLoadIdentity();  
      glRotatef(-90,1.0,0.0,0.0);
      glRotatef(month,0.0,1.0,0.0);
	   glTranslatef(moonMarsOrbit,0.0,0.0);
      glRotatef(90,1.0,0.0,0.0);    
      glGetFloatv(GL_MODELVIEW_MATRIX, moonMars.m);
   glPopMatrix();
}

void init(void)
{	
    glClearColor(0.0, 0.0, 0.0, 1.0);   
    glEnable(GL_DEPTH_TEST);  
    glCullFace(GL_BACK);
    glEnable(GL_CULL_FACE);
 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);   
           
    about();    
    solarsystem();
}

void display(void)
{
    glClear(GL_COLOR_BUFFER_BIT| GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    gluLookAt(0.0, 10.0, 15.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0);
    
    sceneGraphTraversal(&sun);

    glutSwapBuffers();   
}

void reshape(int w, int h)
{
    glViewport(0,0, (GLsizei) w, (GLsizei) h);

    glClearColor(0.0,0.0,0.0,1.0); 
    glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
    glMatrixMode(GL_PROJECTION);
       glLoadIdentity();
       gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 50000000000.0);
	    glRotatef(-90.0, 0.0, 0.0, 1.0);
}

void keyboard(unsigned char key, int x, int y)
{
    switch( key ) {
       case 'r':
       case 'R': 
           day = 0; 
           year = 0;
           month = 0;
           moveEarth();
           moveMoon();
           glutPostRedisplay();
           break;
       case 'd':
       case 'D':
           day=(day + incDay) % 360;
           moveEarth(); 
           moveMoon();
           glutPostRedisplay();
           break;
       case 'm':
       case 'M':
           month = (month + incMonth) % 360;
           moveEarth();
           moveMoon();
           glutPostRedisplay();
           break;
       case 'y':
       case 'Y':
           year=(year + incYear) % 360;
           moveEarth();
           glutPostRedisplay();
           break;
       case 'o':
       case 'O':
           day = (day + incDay) % 360;
           year = (year + incYear) %360;
           month = (month + incMonth) % 360;
           moveEarth();
           moveMoon();
           glutPostRedisplay();
           break;           
       case 'p':
       case 'P':
           autoplay = true;
           cout << "Autoplay on!\n";
           break;
       case 's':
       case 'S':
           autoplay = false;
           cout << "Autoplay off!\n";
           glutPostRedisplay();
           break;            
       case 'i': about();
                 break;    	
	case 'q':
	case 'Q': exit(0);
	default:
			  break;
	}
}

void about(void)
{
    cout << "--------------------------------------------" << endl;
    cout << " Sonnensystem mit Szenengraphen             " << endl;
    cout << "                                            " << endl;
    cout << " r/R: Ausgangsposition einnehmen            " << endl;
    cout << " d/D: Drehung der Erde um sich selbst       " << endl;
    cout << " y/Y: Drehung der Erde um die Sonne         " << endl;
    cout << " m/M: Drehung des Mondes um die Erde        " << endl;
    cout << " o/O: Bewegung des gesamten Systems         " << endl;
    cout << " p/P: Autoplay an                           " << endl;
    cout << " s/S: Autoplay aus                          " << endl;
    cout << "   i: Diesen Text ausgeben                  " << endl;    
    cout << endl;
    cout << " q/Q: Programm beenden                      " << endl;
    cout << "--------------------------------------------" << endl;	
}

void mouseMenu(int id)
{
    switch (id) {
		case 1: exit(0);
		default:
			break;
	}
}

void cbacks(void)
{

    glutDisplayFunc(display);
    glutKeyboardFunc(keyboard);
    glutReshapeFunc(reshape);
    glutIdleFunc(autorun);    
    glutCreateMenu(mouseMenu);
       glutAddMenuEntry("Quit",1);
    glutAttachMenu(GLUT_RIGHT_BUTTON);
    return;
}

void autorun(void)
{
   _sleep(40);
   if (autoplay) {
      day = (day + incDay) % 360;
      year = (year + incYear) %360;
      month = (month + incMonth) % 360;
      moveEarth();
      moveMoon();
      moveMars();
      moveMoonMars();
   }
   glutPostRedisplay();
   //glutSwapBuffers();
}


glutcallbacks.h
Code:
#ifndef GLUTCALL
#define GLUTCALL

#include <gl\glut.h>
void about(void);
void init(void);
void cbacks(void);
void display(void);
void reshape(int width, int height);
void idle(void);
void mouse(int btn, int state, int x, int y);
void keyboard(unsigned char key, int x, int y);
void mouseMotion(int x, int y);
void mouseMenu(int id);
void solarsystem();
void drawSun(void);
void drawEarth(void);
void drawMoon(void);
void drawMars(void);
void drawMoonMars(void);
void moveSun(void);
void moveEarth(void);
void moveMoon(void);
void moveMars(void);
void moveMoonMars(void);
void autorun(void);
#endif
 
Wenn ich mich da jetzt nochmal dransetzen würde, müsste ich dann Pluto mitberechnen? Ist ja kein "richtiger" Planet mehr.
 
Musst du natürlich nicht, Aber wenn du es tust, dann soltest du auch den mit reinnehmen, der den Pluto "Deplanetisiert" hat. Also der neue da von dem mir jetzt der Name nicht einfällt. Du weist schon was ich meine oder. :D ?(
 
Soweit ich weiß ham die Pluto nur rausgeschmissen und keinen neuen reingetan.

Naja, man muss nur lange genug warten, dann löst sich wenigstens ein Teil des Problems von alleine :D
 
Also da dieser thread ja heute wieder aktiv geworden ist und sonst nicht besseres zu tun hatte ;-) hab ich mal versucht das auszurechnen.

Bei mir kommt dieses Ergebniss:
Eine Periode ist 1.0546488354229E+053 Stunden lang.

In wie weit das Ergebniss richtig ist weiss ich nicht. Hoffe aber mal das ich nicht all zu weit danneben lieg

Ich hab übrigens den Pluto auch mit einbezogen, mit den Daten die es am anfang von diesem Thread gab, also wenn ich morgen wieder Zeit(oder Lust?) hab schreib ich das Programm noch mal um.

Jon2

PHP:
<?php

$Planet[0]=array("Merkur", "39", "478");
$Planet[1]=array("Venus", "72", "350");
$Planet[2]=array("Erde", "100", "298");
$Planet[3]=array("Mars", "152", "241");
$Planet[4]=array("Jupiter", "520", "130");
$Planet[5]=array("Saturn", "954", "96");
$Planet[6]=array("Uranus", "1920", "68");
$Planet[7]=array("Neptun", "3006", "54");
$Planet[8]=array("Pluto", "3960", "47");

$pi = "3141592654";

for($i=0; $i < count($Planet); $i++) {
  //Umlaufbahn des Planeten berechnen:
  $Planet[$i][1] = (($Planet[$i][1] / 100) * 149600000) * 2 * ($pi/1000000000);
	//Zeit des Umkreisens der Sonne berechnen (in sekunden)
	$Planet[$i][3] = $Planet[$i][1]/($Planet[$i][2]/100);
	//Zeit des Umkreisens der Sonne berechnen (in Stunden)
	$Planet[$i][3] = (($Planet[$i][3]/60)/60);
  //auf Stunden runden sonst müsst ich mich ja mit den komischen Komma zahlen rumaergern
	$Planet[$i][3] = round($Planet[$i][3]);
}

//so jetzt muss ich noch den Kgv finden....wenn das mal so einfach waere
$x = 3;
$ggt=1;
while($x*$x < $Planet[8][3]) {
  $y = 2;
	$prim = 0;
  while ($y < $x){
	  if (is_int($x/$y)) {
		  $prim = 1;
		}
	  $y++;
	}
	if ($prim == 0) {
	  if (is_int($Planet[8][3]/$x)) {
		  if (is_int($Planet[7][3]/$x)) {
			  if (is_int($Planet[6][3]/$x)) {
				  if (is_int($Planet[5][3]/$x)) {
					  if (is_int($Planet[4][3]/$x)) {
						  if (is_int($Planet[3][3]/$x)) {
							  if (is_int($Planet[2][3]/$x)) {
								  if (is_int($Planet[1][3]/$x)) {
									  if (is_int($Planet[0][3]/$x)) {
										  $ggt = $ggt*$x;
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
  $x++;
}

$Planet[0][3] = $Planet[0][3]/$ggt;
$Planet[1][3] = $Planet[1][3]/$ggt;
$Planet[2][3] = $Planet[2][3]/$ggt;
$Planet[3][3] = $Planet[3][3]/$ggt;
$Planet[4][3] = $Planet[4][3]/$ggt;
$Planet[5][3] = $Planet[5][3]/$ggt;
$Planet[6][3] = $Planet[6][3]/$ggt;
$Planet[7][3] = $Planet[7][3]/$ggt;
$Planet[8][3] = $Planet[8][3]/$ggt;

$Periode = $Planet[0][3]*$Planet[1][3]*$Planet[2][3]*$Planet[3][3]*$Planet[4][3]*$Planet[5][3]*$Planet[6][3]*$Planet[7][3]*$Planet[8][3];

print "Eine Periode ist ".$Periode." Stunden lang";
?>
 
Zurück
Oben