Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Till

Alter Hase

  • »Till« ist der Autor dieses Themas

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

11

18.02.2005, 20:45

VERDAMMT! Das mit dem 10.000 Mal Move pro Frame ist viel zu FrameRate-Lastig (bei zehn Teilchen vielleicht 0.2 FPS :angel: ).
Dann muss ich wohl doch wieder auf meinen Kräfteschwund für

C-/C++-Quelltext

1
abs(r) < 1.0f
zurückgreifen... *heul*
Oder fällt jemandem was besseres ein?
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

David Scherfgen

Administrator

Beiträge: 10 382

Wohnort: Hildesheim

Beruf: Wissenschaftlicher Mitarbeiter

  • Private Nachricht senden

12

19.02.2005, 10:50

Zitat von »"Till"«

Es gibt doch sicher Physik-Engines mit Gravitation! Wie machen die das???

Dort ist die Gravitation aber immer konstant (z.B. immer mit 9,81 m/s² nach unten). Mir ist keine Engine bekannt, die zwei sich anziehende Massen direkt simulieren kann.

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

13

19.02.2005, 11:02

Zitat


Ich vermute, das liegt daran, dass ich keine unendlich hohe Framerate habe und die Kraft nicht kontinuierlich mit der Zeit wirkt.


Das ist durchaus möglich. Ein Mittel dagegen ist in der Tat eine kleine Schrittweite. Diese würde ich nicht konstant lassen, sondern "den Anforderungen entsprechend anpassen". Merk Dir die zuletzt berechnete Kraft und die neue und wenn die z.B. mehr als 5% auseinenander liegen, verringerst Du (diese? die nächste?) Schrittweite. Umgekehrt, wenn es kleiner als sagen wir 1% ist, erhöhst Du es wieder.

Ich vermute, Du hast das ganze praktisch eindimensional angelegt, d.h. der Radius wird zu einem Moment exakt Null? Wie wäre es, die leicht aneinander vorbeifliegen zu lassen?

Du nimmst double, oder?

Zitat

(Kann ich diese lineare interpolation "zwischen" den Frames vielleicht ausgleichen, indem ich die Kraft "quadratisch" zur Zeit anwende? Wie müsste ich es denn dann machen?).


Ja, das geht.

Disclaimer: Ich weiss, dass man so vorgehen kann, aber hadbe die Details vergessen :(. Daher hab ichs mir gerade überlegt, es müsste richtig sein, aber vielleicht nicht optimal. Ein paar Denkanstöße:

Die jetzige Methode ist ja, dass du sagst, während eines Schrittes ist die Kraft und damit Beschleunigung ungefähr konstant, a = a0.
a bekommst Du mit a = F / m. Du näherst also v mit v0 + a0 * t an, woraus sich eben das v-v0 = a0 * t ergibt.

Jetzt nehmen wir einen quadratischen Term hinzu und nehmen den Ansatz:

v = v0 + a0 * t + b0 * t**2

Wobei b0 eine Konstante (innerhalb des Schrittes) ist. a(t) ist die Ableitung von v nach t, d.h.

a = a0 + 2 * b0 *t.
Sagen wir mal bei t=0 sei a = a0 (kleiner Scherz um zu sehen, ob Ihr noch nicht schläft :-D ) und bei t=t1 sei a = a1. Dann

a1 = a0 + 2 * b0 * t1

Damit hast Du IMHO alle Gleuichungen, die Du braucht. Du nimmst die beiden beschleunigungen aus den beiden letzten Schritten und hast dann a0 und a1. Du arbeitest in einem Zeitkoordinatensystem, indem the Zeit = 0 ist bei dem vorherigen Schritt, in anderen Worten, speziell für diese Gleichungen nimmst Du für jeden Schritt ein neues System :P . Dann kannst Du mit der letzten Gleichung b0 berechnen (für diesen Schritt). Die Geschwindigkeit erhöht sich dann um a0 * t + b0 * t**2, wobei t die Schrittweite ist.

Hast Du mal geschaut, wie gross die auftretenden Zahlen sind?
"Games are algorithmic entertainment."

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

14

19.02.2005, 11:15

Steven77 hat folgendes geschrieben:

Zitat


...oder Du testest bei jeder Aktualisierung der Positionen, ob zwei Teilchen aneinander vorbeigeflogen sind. Wenn dem so ist, dann sollen die beiden Teilchen die gleiche Entfernung zueinander haben, wie vor dem Vorbeiflug. Dann sind die potenziellen Energien beider Teilchen zueinander die selben, wie vor dem Vorbeiflug und es ist weder Energie dazugekommen, noch abgeflossen.
(Oder vertue ich mich da jetzt?)


Till schrieb:

Zitat


Nein, es ist ja eine Simulation, bei der zu jedem Zeitpunkt wirkende Kräfte (und das können 'ne Menge sein!) die Teilchen beeinflussen. Also kann ich nicht "mogeln", indem ich Positionen anpasse.


Wenn Du schon extrem nahe vorbeiflüge oder sogar r=0 hats, dann ist Till m.E. auf einem guten Weg. Die Zeit in Schritte aufzuteilen ist ja ein problem und eigentlich ein mogeln, aber beim digitalen Computer eben unumgänglich. Kleinere Schrittweite = weniger mogeln (bessere Annäherung an die Wirklichkeit), aber eben auch langsamere Simulation. Seh es so: Der Fall r=0 darf eigentlich nicht auftreten und m.E. ist Dein Fehler, dass er auftritt. So klein Du Deine Schrittweite auch machst, in dem Schritt über die Null (z.B. von x = - 0.0001 bis x = 0.0003) überspringst Du 100% der Physik, die geschieht. In dem Bereich ist die Änderung der Potentiellen Energie unendlich, ausserhalb endlich. M.E. ist Dein problem, warum Du immer eine Energiezunahmen (und nicht z.B. zufällig Zu- oder Abnahme) hast, dass beim letzten Schritt vor Null eine Riesen Kraft auftritt, daher auf der nächste Schritt auf der anderen Seite weiter von Null entfernt als dieser Schritt vor Null war, wie eben in meinem Beispiel Damit hast Du in diesem Schritt eine grössere positive Beschleunigung als im nächsten Schritt eine negative, was zu der Energiezufuhr führt. Wenn Du in diesem Schritt die Zeit so begrenzt, dass die beien x Werte abosolut gesehen identisch sind, dann hast Du die selbe negative Beschleunigung wie vorher positive und die Physik zwischen x und Null, die Du wegschmeisst, ist auf beiden Seiten die selbe, nur eben umgedreht.
"Games are algorithmic entertainment."

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

15

19.02.2005, 11:32

Meine obigen Posts haben gezeigt, wie man m.E. mit r=0 umgehen müsste.

Aber wieso kommt es zu r=0? Ist Dein System zwei dimensional? Starten die Teilen mit v=0 ? Wenn ja, mal zufällige, kleine Anfangsgeschwindigkeiten setzen ;).

Zitat


Dort ist die Gravitation aber immer konstant (z.B. immer mit 9,81 m/s² nach unten). Mir ist keine Engine bekannt, die zwei sich anziehende Massen direkt simulieren kann.


Bei den meisten Spielen sicher richtig, da r konstant ist. Das zwei Körper Problem ist analytisch lösbar, ab 3 Körpern muss man es numerisch lösen. Natürlich gibt es da etliche Engines. Eine Profilösung würde wahrscheinlich so aussehen:

1. Mathematische Grundlage sind Differntialgleichungen (DGL), in diesem Fall die von Maxwell.
2. Es wird untersucht, was für ein Typ von DGL vorliegt. z.B. gibt es "steife" DGLs, die besonders schwer zu lösen sind. Es ist jetzt 15 Jahre her, daß ich das gemacht habe, aber IMHO bedeutet es "einfach", daß Rechenfehler sich besonders stark akkumulieren.
3. Je nach Typ geeignetes Verfahren zur numerischen Behandlung suchen, also z.B. Runge Kutta, Euler etc.
4. Schrittweitenanpassung.
5. Super ist es natürlich, wenn neben dem Wert auch die maximale Abweichung berechnet wird.
6. Ich bin mir ziemlich sicher, daß gute Syteme (spätestens bei Schritt 5) bei R=0 eine fehlermeldung generieren würden.
7. Simulationen für Teilchenbeschleuniger (aber auch z.B. die für Satelliten!) müssen auch relativistische Effekte berücksichtigen.
"Games are algorithmic entertainment."

Anonymous

unregistriert

16

19.02.2005, 12:24

Ich meinte das eigentlich anders. Der Zeitwert ist immer konstant:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
const float Zeitwert=0.1f;//bissel ungenau, aber nur ein Bsp
float VergangeneZeit=0;
while(true)
{
  //Nachrichten
  VergangeneZeit+=????;
  while(VergangeneZeit>Zeitwert)
  {
    VergangeneZeit-=ZeitWert;
    Move(Zeitwert);
  }
  Render();
}

so kann man sogar die Multiplikation mit den Zeitwert in der Movemethode praktisch weglassen, da dieser immer gleich ist. Wenn die Movemethode aber langsamer ist, als Zeitwert, wirst du nicht mehr viele Bilder mehr sehen:)

Dein Problem wird das aber nicht lösen. Ich glaube eher, dass deine Formel falsch ist.

Ciao

Till

Alter Hase

  • »Till« ist der Autor dieses Themas

Beiträge: 378

Wohnort: Lincoln College, Oxford

Beruf: Student

  • Private Nachricht senden

17

20.02.2005, 20:11

OK, erst mal sorry, dass ich so lange weg war (das Wochenende), aber ich musste einfach noch mal Snowboarden (bei dem Wetter :krank: )...

Aaaalso...

Zitat von »"Osram"«

Wenn Du schon extrem nahe vorbeiflüge oder sogar r=0 hats, dann ist Till m.E. auf einem guten Weg. Die Zeit in Schritte aufzuteilen ist ja ein problem und eigentlich ein mogeln, aber beim digitalen Computer eben unumgänglich. Kleinere Schrittweite = weniger mogeln (bessere Annäherung an die Wirklichkeit), aber eben auch langsamere Simulation. Seh es so: Der Fall r=0 darf eigentlich nicht auftreten und m.E. ist Dein Fehler, dass er auftritt. So klein Du Deine Schrittweite auch machst, in dem Schritt über die Null (z.B. von x = - 0.0001 bis x = 0.0003) überspringst Du 100% der Physik, die geschieht. In dem Bereich ist die Änderung der Potentiellen Energie unendlich, ausserhalb endlich. M.E. ist Dein problem, warum Du immer eine Energiezunahmen (und nicht z.B. zufällig Zu- oder Abnahme) hast, dass beim letzten Schritt vor Null eine Riesen Kraft auftritt, daher auf der nächste Schritt auf der anderen Seite weiter von Null entfernt als dieser Schritt vor Null war, wie eben in meinem Beispiel Damit hast Du in diesem Schritt eine grössere positive Beschleunigung als im nächsten Schritt eine negative, was zu der Energiezufuhr führt. Wenn Du in diesem Schritt die Zeit so begrenzt, dass die beien x Werte abosolut gesehen identisch sind, dann hast Du die selbe negative Beschleunigung wie vorher positive und die Physik zwischen x und Null, die Du wegschmeisst, ist auf beiden Seiten die selbe, nur eben umgedreht.


OK, das Problem mit r=0 kann ja durch Überprüfen behoben werden, aber das Problem wird eben sein, dass bei einem Frame bei r fast 0 die Geschwindigkeit so hoch wird, dass des Teilchen beim nächsten Frame zu weit weg ist. Aber um die potentielle Energien zu erhalten und die Frames "symmetrisch" zur Bewegung ablaufen, brauche ich ja irgendeine Synchronisierung, das blöde ist aber ja, dass das System groß ist und ich nicht wissen kann, wie viele Felder und Teilchen der Benutzer erstellt. Wie synchronisiere ich das dann also?
Ich habe nun ein einigermaßen zufriedenstellende Mischung aus mehreren Move-Aufrüfen und Näherungsgrenze (ab 1.2f ist schluss mit Kraft...). Das mit der quadratischen Wirkung über die Zeit schaue ich mal an, denn ich weiß nicht, wie FPS-lastig meine momentane Lösung auf anderen CPUs ist. Aber mit DGLs kann ich nicht viel machen, ich bin erst Schüler in Klasse 12, bin zwar (mit Abstand) der Beste in Mathe und Physik, aber das Projekt soll nicht gerade mein Lebenswerk werden :-D

Jedenfalls danke für die bisherigen Ratschläge!

PS: Ach ja, ich benutzte D3DXVECTOR3s und das sind doch FLOATs, oder (32 bit dachte ich)?
DOMINVS ILLVMINATIO MEA
---
Es lebe unmanaged Code!
---
>> Meine Uni <<

Osram

Alter Hase

Beiträge: 889

Wohnort: Weissenthurm

Beruf: SW Entwickler

  • Private Nachricht senden

18

20.02.2005, 21:12

Zitat


OK, das Problem mit r=0 kann ja durch Überprüfen behoben werden, aber das Problem wird eben sein, dass bei einem Frame bei r fast 0 die Geschwindigkeit so hoch wird, dass des Teilchen beim nächsten Frame zu weit weg ist.


Ja, genau.

Zitat


Aber um die potentielle Energien zu erhalten und die Frames "symmetrisch" zur Bewegung ablaufen, brauche ich ja irgendeine Synchronisierung, das blöde ist aber ja, dass das System groß ist und ich nicht wissen kann, wie viele Felder und Teilchen der Benutzer erstellt. Wie synchronisiere ich das dann also?


Das würde ich so machen:
Bei der "normalen" Kraft berechnung, bei der ja sowieso all Rs berechnet werden, einfach das Minimum "mitlaufen lassen". Wenn das minimal R kleiner ist als das momentane delta t erlaubt, dann delta t runter schrauben.

Zitat


Aber mit DGLs kann ich nicht viel machen, ich bin erst Schüler in Klasse 12,


Ich finde es sowieso beeindruckend, dass Du das überhaupt machst. Ich weiss nicht, ob ich das damals hinbekommen hätte.
<Osram sucht das Hut-ab smilie>

Zitat


das Projekt soll nicht gerade mein Lebenswerk werden


Ja ok :-D :huhu:

Mich würde aber schon interesieren, wie Deine Anfangsbedingungen aussehen bzw wieso Du zu so kleinen Rs kommst. IMHO sollte das nicht passieren.

Zitat


PS: Ach ja, ich benutzte D3DXVECTOR3s und das sind doch FLOATs, oder (32 bit dachte ich)?


Stimmt. Das ist definitiv nicht optimal. Du könntest Dir eine eigene Klasse, auf double basierend schaffen und vorm Rendern in D3DXVECTOR3 konvertieren.
"Games are algorithmic entertainment."

Werbeanzeige