Autor Beitrag
Mathematiker
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Do 12.11.15 00:58 
Hallo,
ich habe noch einmal ein kleines Programm zum Thema Astronomie. Das Programm simuliert die Keplerschen Gesetze.

kepler

Dabei wird die Bewegung des Planeten direkt aus dem Winkel bzgl. Ellipsenmitte und der Exzentrizität der Bahn berechnet. Beim 2.Gesetz, dem Flächensatz, werden die 2 gleich großen Ellipsensegmente durch Zeitmessung während der Simulation bestimmt. Das war notwendig und problematisch, da die Berechnung des Ellipsenbogens aus der Fläche des Ellipsensegments nicht einfach ist, funktioniert aber jetzt.

Noch zur Erklärung: Die Exzentrizitäten der zwei Bahnen werden in den Spinedits mit dem Faktor 100 angegeben. Normalerweise liegen sie ja zwischen 0 und 0,99999...
Im Programm wird die Kepler-Gleichung benötigt.
ExAnomalie
Dabei ist die exzentrische Anomalie der Winkel E zwischen der großen Halbachse und einem durch den Ellipsenmittelpunkt O gehenden Kreisradius (Kreisradius = große Halbachse). Dieser Radius schneidet den Kreis in dem Punkt, welcher durch eine Senkrechte durch den gegebenen Ellipsenpunkt P geschnitten wird.
Die mittlere Anomalie M kann geometrisch interpretiert werden und entspricht dem Flächeninhalt der in der Abbildung gelb gefärbten Fläche.
Die Kepler-Gleichung ist
M = E - e sin E
leider nicht analytisch lösbar. Daher benötigt man eine Näherungslösung.

Das Programm ist eigentlich nur ein "Rahmen". Wer es braucht, kann es ja entsprechend erweitern.
Zumindest ist die Planetengeschwindigkeit korrekt in Sonnennähe größer als in Sonnenferne, und ausschließlich durch reine mathematische Berechnung ermittelt. :D

Beste Grüße
Mathematiker
Einloggen, um Attachments anzusehen!
_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein

Für diesen Beitrag haben gedankt: Delphi-Laie, Horst_H
hathor
Ehemaliges Mitglied
Erhaltene Danke: 1



BeitragVerfasst: Do 12.11.15 15:19 
user profile iconMathematiker hat folgendes geschrieben Zum zitierten Posting springen:
...Zumindest ist die Planetengeschwindigkeit korrekt in Sonnennähe größer als in Sonnenferne, und ausschließlich durch reine mathematische Berechnung ermittelt. :D

Beste Grüße
Mathematiker


Stimmt es, dass dies für Galaxien NICHT gilt?
Da ist angeblich die Winkelgeschwindigkeit für alle Massen gleich.
Stichwort "Dunkle Materie".
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 12.11.15 17:15 
Hallo,

bei mir lief es etwas CPU rauchend mit 100% unter Linux/wine.
Ich habe es mal mit Lazarus probiert.Wie auch bei dem anderen Programm von Dir mit den Planeten und Kometen, einfach sich nicht ändernde Dinge vorabgezeichnet.
Die Zeitbestimmung habe ich komplett geändert.Da die Prozedur Paintbox1P regelmäßig aus dem Timer heraus aufgerufen wird, habe ich einfach dafür gesorgt, das bei der Anzeige der überstrichenen Flächen gleich viele Punkte aufgenommen werden.
So bin ich bei FullHd-Vollbild bei 50%.Ich habe den Timer auf 16 ms gestellt, das passt besser zu den 60 Hz vom Bildschirm.
Ich hoffe, es funktioniert auch unter Delphi.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
unit ukepler;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses
{$IFnDEF FPC}
  Windows,
{$ELSE}
  LCLIntf, LCLType, LMessages,
{$ENDIF}
  Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Spin;

type

  TLargeInteger = Int64;

  { TForm1 }

  TForm1 = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    PaintBox1: TPaintBox;
    SpinEdit1: TSpinEdit;
    SpinEdit2: TSpinEdit;
    RadioButton1: TRadioButton;
    RadioButton2: TRadioButton;
    RadioButton3: TRadioButton;
    SpinEdit3: TSpinEdit;
    Timer1: TTimer;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
    procedure FormResize(Sender: TObject);
    procedure Paintbox1P(Sender: TObject);
    procedure FormShow(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    procedure SpinEdit1Change(Sender: TObject);
  private
    bmp1Planet,
    bmp,bmp2Planets : tBitmap;
    kep1,kep2,mx,my:integer;
    ob,ob2:array[0..460of tpoint;
    epsilon,epsilon2 : double;
    a,b,e,a2,e2,b2,
    wkepler,
    wi,wkepler2:double;
    procedure myBitmapInit(Sender: TObject);
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$IFnDEF FPC}
  {$R *.dfm}
{$ELSE}
  {$R *.lfm}
{$ENDIF}

function keplerg(m,e:double):double;
 var ea,eo:double;
 begin
   ea:=m;
   eo:=0;
   while abs(eo-ea)>0.007 do begin
     eo:=ea;
     ea:=m+e*sin(ea);
   end;
   result:=ea;
   //wahre anomalie
 end;

procedure TForm1.myBitmapInit(Sender: TObject);
const
  k = 'Sonne';
var
  can: tCanvas;
begin
  IF bmp1Planet<> NIL then
    freeAndNil(bmp1Planet);
  bmp1Planet:=tbitmap.create;
  bmp1Planet.width:=paintbox1.width;
  bmp1Planet.Height:=paintbox1.Height;

  can:=bmp1Planet.canvas;
  can.Brush.Style:= bsSolid;
  can.Brush.Color:= clwindow;
  can.Rectangle(can.ClipRect);
  can.Font.name:='Verdana';

    //Werte der Planetenbahnen
  epsilon:=spinedit1.value/100;
  a:=(bmp1Planet.width-150)/2;
  e:=a*epsilon;
  b:=sqrt(a*a-e*e);
  if b>(bmp1Planet.height-80)/2 then begin
    b:=(bmp1Planet.height-80)/2;
    a:=sqrt(b*b/(1-epsilon*epsilon));
    e:=a*epsilon;
  end;

  epsilon2:=spinedit2.value/100;
  a2:=a*0.629961;
  e2:=a2*epsilon2;
  b2:=sqrt(a2*a2-e2*e2);

  //Halbachsen
  mx:=bmp1Planet.width div 2;
  my:=bmp1Planet.height div 2;
  can.pen.color:=clgreen;
  can.moveto(round(mx-a-10),my);
  can.lineto(round(mx+a+10),my);
  can.moveto(mx,round(my-b-10));
  can.lineto(mx,round(my+b+10));

  can.brush.style:=bsSolid;
  can.pen.color:=clyellow;
  can.brush.color:=clyellow;
  can.ellipse(round(mx-e-10),my-10,round(mx-e+11),my+11);
  //Planetenbahn
  can.brush.style:=bsclear;
  can.font.color:=clBlack;
  can.textout(round(mx-e-can.textwidth(k) div 2),my+10,k);
  can.pen.color:=clblue;
  can.ellipse(round(mx-a),round(my-b),round(mx+a+1),round(my+b+1));
  bmp.Assign(bmp1Planet);

  bmp2Planets.Assign(bmp1Planet);
  can:=bmp2Planets.canvas;
  can.Brush.Style:= bsClear;
  can.pen.color := clfuchsia;
  bmp2Planets.canvas.ellipse(round(mx-e+e2-a2),round(my-b2),round(mx-e+e2+a2+1),round(my+b2+1));
end;

procedure TForm1.Paintbox1P(Sender: TObject);
var
    i,xp,yp,xp2,yp2:integer;
    punkte:array[0..460of tpoint;
    k:string;
    can:tcanvas;
 //Loesung der Kepler-Gleichung
 begin
  //Eine vorgezeichnete Bitmap kopieren
  if radiobutton3.checked then
    bmp.Canvas.draw(0,0,bmp2Planets)
  else
    bmp.Canvas.draw(0,0,bmp1Planet);

  can := bmp.Canvas;

  xp2:=0;
  yp2:=0;

  //Zeichnung der Ellipsensegmente beim 2.Gesetz
  if radiobutton2.checked then begin
    can.pen.color:=clgray;
    //1.Fläche
    if kep1>0 then begin
      can.brush.style:=bsbdiagonal;
      can.brush.color:=clyellow;
      for i:=0 to kep1-1 do begin
        punkte[i].x:=ob[i].x;
        punkte[i].y:=ob[i].y;
      end;
      punkte[kep1].x:=round(mx-e);
      punkte[kep1].y:=my;
      can.polygon(slice(punkte,kep1+1));
    end;
    //2.Fläche
    if kep2>0 then begin
      can.brush.style:=bsbdiagonal;
      can.brush.color:=cllime;
      for i:=0 to kep2-1 do begin
        punkte[i].x:=ob2[i].x;
        punkte[i].y:=ob2[i].y;
      end;
      punkte[kep2].x:=round(mx-e);
      punkte[kep2].y:=my;
      can.polygon(slice(punkte,kep2+1));
    end;

    if (spinedit3.value>0and (spinedit3.value<20then begin
      kep1:=0;
      kep2:=0;
    end;
  end;

  //Berechnung des 1.Planeten
  wi:=spinedit3.value*pi/180;
  wkepler:=keplerg(wi,epsilon);
  xp:=round(mx-a*cos(wkepler));
  yp:=round(my-b*sin(wkepler));

  can.brush.Style:=bsClear;
  can.pen.color:=clfuchsia;
  can.moveto(round(mx-e),my);
  can.lineto(xp,yp);

  //v(r) = sqrt(g M (2/r - 1/a))
  can.pen.color:=clblack;
  can.brush.color:=clred;
  can.brush.style:=bssolid;
  can.ellipse(xp-5,yp-5,xp+6,yp+6);

  //Lage des 2.Planeten
  if radiobutton3.checked then begin
    wi:=2*spinedit3.value*pi/180+pi/4;
    wkepler2:=keplerg(wi,epsilon2);
    xp2:=round(mx-e+e2-a2*cos(wkepler2));
    yp2:=round(my-b2*sin(wkepler2));
    can.brush.color:=clnavy;
    can.ellipse(xp2-5,yp2-5,xp2+6,yp2+6);
  end;

  //Zeitabhängige Flächen beim 2.Gesetz ermitteln
  if radiobutton2.checked then begin
    if (spinedit3.value <=5then
      kep1:=0
    else
      if (spinedit3.value <=90then
      Begin
        ob[kep1].x:=xp;
        ob[kep1].y:=yp;
        inc(kep1);
      end;
    if spinedit3.value <=round(100+20*(1+epsilon)) then
      kep2:=0
    else
      if kep2<kep1 then begin
        ob2[kep2].x:=xp;
        ob2[kep2].y:=yp;
        inc(kep2);
      end;
    end;

  k:='Planet';
  can.brush.Style:=bsClear;
  can.textout(xp-can.textwidth(k) div 2,yp+9,k);
  if radiobutton3.checked then
    can.textout(xp2-can.textwidth(k) div 2,yp2+9,k);

  paintbox1.Canvas.draw(0,0,bmp);
end;

procedure TForm1.FormClose(Sender: TObject; var CloseAction: TCloseAction);
begin
  bmp1Planet.Free;
  bmp.free;
  bmp2Planets.free;
end;

procedure TForm1.FormResize(Sender: TObject);
begin
  FormShow(sender);
end;

procedure TForm1.FormShow(Sender: TObject);
begin
   kep1:=0;
   kep2:=0;
   bmp:= TBitmap.create;
   bmp2Planets:= TBitmap.create;
   myBitmapInit(Sender);
   bmp.Assign(bmp1Planet);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
   timer1.Enabled:=not timer1.Enabled;
end;

procedure TForm1.Timer1Timer(Sender: TObject);
var x:integer;
begin
   x:=spinedit3.value+1;
   if x>spinedit3.MaxValue then x:=spinedit3.minvalue;
   spinedit3.Value:=x;
end;

procedure TForm1.SpinEdit1Change(Sender: TObject);
begin
   kep1:=0;
   kep2:=0;
   epsilon:=spinedit1.value/100;
   myBitmapInit(Sender);
   paintbox1p(sender);
end;

end.


Gruß Horst

Für diesen Beitrag haben gedankt: Mathematiker
Mathematiker Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 2622
Erhaltene Danke: 1447

Win 7, 8.1, 10
Delphi 5, 7, 10.1
BeitragVerfasst: Do 12.11.15 18:28 
Hallo Horst_H,
Danke für die Änderungen. Durch das "Vorzeichnen" der sich nicht ändernden Sachen wird der Prozessor deutlich entlastet und es funktioniert mit Delphi perfekt. :zustimm:
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Die Zeitbestimmung habe ich komplett geändert.Da die Prozedur Paintbox1P regelmäßig aus dem Timer heraus aufgerufen wird, habe ich einfach dafür gesorgt, das bei der Anzeige der überstrichenen Flächen gleich viele Punkte aufgenommen werden.

Das sehe ich mir genauer an, da ich mir nicht ganz sicher bin, ob die Flächen flächengleich sind. Es sieht zwar so aus, aber die Mathematik hinter deiner Lösung habe ich noch nicht verstanden.

Hallo hathor,
user profile iconhathor hat folgendes geschrieben Zum zitierten Posting springen:
Stimmt es, dass dies für Galaxien NICHT gilt?
Da ist angeblich die Winkelgeschwindigkeit für alle Massen gleich.

Die Bewegung innerhalb der Galaxis ist extrem kompliziert und im Moment Top-Forschungsobjekt. Zumindest gelten die Keplerschen Gesetze nur bedingt, da sonst die Spiralstruktur schon nach wenigen Umläufen nicht mehr existieren würde.
Es ist sehr interessant, aber auch entsprechend kompliziert.

Beste Grüße
Mathematiker

_________________
Töten im Krieg ist nach meiner Auffassung um nichts besser als gewöhnlicher Mord. Albert Einstein
Horst_H
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1652
Erhaltene Danke: 243

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: Do 12.11.15 22:26 
Hallo,

schon wieder ein extrem weiter "Planet" um die Sonne gefunden.
www.heise.de/newstic...ntdeckt-2919289.html.
Wenn die Umlaufbahn bekannt ist, kann der ja in www.entwickler-ecke....ewtopic.php?t=113651 eingepfelgt werden ;-)

Meine Zeitberechnug besteht aus keiner Zeitberechnung.Das Programm gibt doch Zeitschritte vor.
Beim zweiten Keplerschen Gesetz heißt es doch gleiche Flächen in gleichen Zeiten.
Wenn ich für den ersten gelben Abschnitt die Anzahl x der Zeitschritte kenne ( x== kep1 ) , brauche ich das für den zweiten Abschnitt ab dem Startzeitpunkt nur diese x Zeitzabschnitte lang eintragen.
ausblenden Delphi-Quelltext
1:
 if kep2<kep1 then begin					

Bei einer Exzentrizität von 0 -> Kreis sieht man es gut.

Gruß Horst

Für diesen Beitrag haben gedankt: Mathematiker
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 13.11.15 17:15 
Kaum angeschaut, schon fällt mir eine Anregung ein: Für das zweite Gesetz könnte man doch Flächen per Zufallsprinzip anzeigen lassen, also mit anderem als immer dem gleichen Start- und Zielpunkt, also auch unterschiedlicher Größe bei unterschiedlichen Zeitabschnitten. Auch könnte man die Anzahl dieser Flächen zufällig wählen lassen (mindestens 2, sonst wäre es nicht sinnvoll). Auch könnten sich diese Flächen zur Not mehr oder weniger überlappen.

Für diesen Beitrag haben gedankt: Mathematiker
Delphi-Laie
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 1600
Erhaltene Danke: 232


Delphi 2 - RAD-Studio 10.1 Berlin
BeitragVerfasst: Fr 13.11.15 20:15 
Ich meinte natürlich mit der Formulierung: "also mit anderem als immer dem gleichen Start- und Zielpunkt, also auch unterschiedlicher Größe bei unterschiedlichen Zeitabschnitten", daß die unterschiedliche Größe der übstrichenen Flächen bzw. die unterschiedlichen Zeiten für ein- und diesselbe Umdrehung natürlich konstant sein muß, da das 2. Gesetz sonst nicht darstellbar ist, ich meinte es für verschiedene Umläufe.

Man könnte die Gesetze ggf. auch noch rechts von der Darstellung die Gesetze als Formel hinschreiben und/oder (beim 2. Gesetz), daß die überstrichenen Flächen gleich sind o.ä.

Lässig wäre es, wenn man beim Größenändern des Formulares die Exzentrizität der Ellipse(n) verändern könnte.

Läßt man die Simulation mit dem 2. Gesetz laufen, so wird die Ellipse in Echtzeit angepaßt (wie auch beim 1. und 3. Gesetz), nicht jedoch die Darstellung der überstrichenen Flächen. Das führt dann zu einer Fehldarstellung.