Timebased Animation, zusätzliche Gedanken zur FAQ
-
text aus dem zusammenhang reissen kann ich auch, das muss ich aber nicht oder?
also setzen wir an:
jeden punkt auf dem weg der flugbahn des geschosses seit dem letzten frame auf kollision testen
ein
(performance, ich komme ;))
und beachten den smiley
ansonsten sit ein
Um den Kollisionspunkt zu erhalten berechnet man einfach den Schnittpunkt von der Flugbahnfunktion mit deinem Kollisionsobjekt
gleichbedeutend mit ausprobieren, immerhin hat man bei einer mathematischen funktion mindestens einen wert den man einsetzen muss. wenn ich bewegung mit konstanter steigung hab, ist die sache ganz einfach: alte position mit neuer mithilfe einer linie verbinden, und dann die kollision objekt/linie verwenden.
bei einer funktion ohne konstante steigung geht das natürlich nicht, also was machen? benutz ich eine linie, kann ich bei einer extrem miesen framezeit die sache vergessen, die linie wird bei kleinen objekten bestimmt nicht das richtige treffen.
Das hauptproblem ist aber auch, dass man ja die bewegung zur zeit ineterpoliert, dh wenn ein objekt die geschwindigkeit 90m/s hat, und man alle 2 sekunden die programmlogik durchläuft,man das objekt um 2*90m verschiebt.
liegt der kollisionspunkt bei 130m kriegst du sofort das problem die richtige kollision zu erkennen. wie gesagt, mithilfe der hilfslinie kann man das noch sehr schön machen, aber wie sollte man zb bei einer parabel vorgehen? das ist das hauptproblem,die bewegung des objekts ist zwar nachvollziehbar,sodass man durch ausprobieren den kollisionspunkt herausbekommen könnte,aber einen performanten trick wie die linie im flal der linearen bewegung gibts halt nicht, ohne dass man einiges an genauigkeit einbüßt.punkt 2:
na ausrechnen oo. Welches Hauptproblem?
dann erklär mir mal, wie man ein objekt auf kollision testen soll, welches sich mit folgender funktion fortbewegt:
f(x)=sin(x).
als rahmenbedingung legen wir noch fest, dass wir 2 fps haben, und ein sinusdurchlauf genau eine sekunde dauert(dh das objekt bewegt sich genau um 360 längeneinheiten pro sekunde genau in richtung der x achse).
-
life schrieb:
Um den Kollisionspunkt zu erhalten berechnet man einfach den Schnittpunkt von der Flugbahnfunktion mit deinem Kollisionsobjekt (beispielsweise ein dreieck). Um dies zutun berechnet man nun einfach die Gradenfunktionen der 3 Seiten und berechnet die Schnittpunkte zwischen Gradenfunktionen und Flugbahnfunktion. Zum Schluss muss man noch gucken ob die Schnittpunkte im gültigen Bereich liegen (die 3 Seiten des Dreieckes sind wahrscheinlich nicht unendlich lang ;)) .. Fertig ist die pixelgenaue kollisionsabfrage, die garantiert völlig unabhängig von deinen fps ist
Das ist nicht pixelgenau.
@otze:
Eine Parabel liegt immerin einer Ebene, nur die muss man betrachten. Schnittpunkte bekommt man einfach durch Gleichsetzen der Gleichungen, 8. Klasse oder sowas.Bye, TGGC \-/
-
dann erklär mir mal, wie man ein objekt auf kollision testen soll, welches sich mit folgender funktion fortbewegt:
f(x)=sin(x).
als rahmenbedingung legen wir noch fest, dass wir 2 fps haben, und ein sinusdurchlauf genau eine sekunde dauert(dh das objekt bewegt sich genau um 360 längeneinheiten pro sekunde genau in richtung der x achse).Gut bei dieser funktion kann man die lösung algebraisch nicht berechnen.. raus bekommt mans aber trotzdem
:
Also rechnen wir einfach mal den Schnittpunkt von der Funktion mit einer Gradenfunktion aus (z.b. y= 1/2*x)
y = sin(x)
y = 1/2 * xsin(x) - 1/2 *x = 0
Gut hier kommt man rechnerisch nicht weiter. Um jetzt die Lösung zu bekommen guckt man zuerst, welches x man eigentlich vor der bewegung hatte und welches nachher. Beispielsweise hatte man vorher pi/2 und nachher pi (daher ist man beim 2. frame). Dann benutzt man ein Nullstellensuchalgorithmus und lässt ihn in diesem bereich drüberlaufen und schwupps hat man seine Lösung (oder auch nicht ;))
-
TGGC schrieb:
Wieso? Wer sagt, du darfst nur mit linearen Funktionen rechnen?
mal stellvertretend den hier nehmen.
stellen wir uns zum verdeutlichen wirklich große sprünge vor. wie sieht die bahn für einen geworfenen ball aus (mit nichts als anfängliche beschleunigung und schwerkraft).
schritt eins:
-ball wird in richtung bewegt mit pos=vt;
-neue richtung durch addieren der v+=gt;bei vielen schritten nähert das brauchbar die flugbahn an.
bei einem großen schritt aber:-ball fliegt viel zu weit mit pos=vfat_t;
-extreme änderung von v mit v+=gfat_t;
-im nächsten frame klatscht das ding schnell nach unten.aus der hübschen kurve wird ein viel zu langer strich in die alte wurfrichtung gefolgt von einem langen strich steil nach unten, der evtl. weit hinter dem eigentlichen aufschlag punkt liegt.
was, wenn man v zuerst aktualisiert und dann die bewegung macht? es wird ein riesen g*fat_t aufaddiert und der ball fällt fast senkrecht nach unten.
deswegen sind nicht lineare bewegungen mit der methode nur dann brauchbar, wenn man sie "sauber" berechnet (nur: will wirklich jemand mit integralen hantieren?)
für das einfache beispiel hier bin ich vor langer zeit mal bei sowas gelandet, um partikel im system auch "mittendrin" starten zu lassen:
pos+=(g*t*t)/2 + (vt);
v+=gt;das sah zumindest optisch richtig aus und irgendwas hab ich mir dabei auch mal gedacht (nur was?)
wenn man davon ausgeht, daß solche updates recht schnell gehen, dann lassen sich nach einem langen frame auch mal mehrere am stück durchziehen. wenn der rechner dann wirklich zu langsam ist, dann kann man immer noch auf größere steps umsteigen. der wesentliche punkt ist einfach, daß das ganze deterministischer abläuft.
kleiner bonus ist vielleicht noch, daß man mit floats davonkommt und bei extremen geschwindigkeiten nicht plötzlich mit lauter t=0 dasteht. dann reicht ein double um die einzelnen framezeiten aufzuaddieren und für die eigentlichen berechnungen reichen wieder handliche floats.
das glätten von spikes ist weniger für korrektheit, sondern für optik. wenn ein frame lange dauert ist die kurze verzögerung schon lästig genug, der folgende sprung umso lästiger. (und ich hoffe mal, die hätten in gpg 4 keinen ähnlich ausgerichteten artikel gepackt, wenn es komplett unsinnig wäre).
anhang: google spuckt da eine lange discussion bei flipcode aus und ein wichtiger punkt fehlte da wirklich noch *hust*.
es kann viel öfter gerendert werden als die spiel logik läuft, rendert man zwischen zwei timesteps wird aber nicht der letzte zustand wiederholt, sondern zwischen beiden interpoliert. dann sind animationen wieder "flüssig" während die "richtigen" berechnungen einfacher sind und/oder seltener durchgeführt werden müssen.
http://www.flipcode.com/cgi-bin/msg.cgi?showThread=Tip-MainLoopTimeSteps&forum=totd&id=-1
-
//edit life hat ja geedited, mein beitrag hat nu keinen sinn mehr-.-
-
?
Ball wird geworfen:xposition nach t sekunden: v * t
yposition nach t sekunden: h - 1/2 * g * t^2 (oder so ~~)
-
life schrieb:
?
Ball wird geworfen:xposition nach t sekunden: v * t
yposition nach t sekunden: h - 1/2 * g * t^2 (oder so ~~)ähm.. oder so... v hat bei dir keinen y anteil (oder auch z).
statt g könnte es auch wind oder jede beliebige andere beschleunigung sein, die nicht zufällig nur in y wirkt. evtl. hätte ich oben erwähnen sollen, daß v und g vektoren sind.oder physik für ein auto. jede menge geschwindigkeiten und beschleunigungen, die wild zusammenwirken.
-
Naja das war jetzt waagerechter wurf .. Es stimmt schon, dass es kompliziert werden kann, aber es ist durchaus möglich das ganze als Funktion darzustellen
-
life schrieb:
Naja das war jetzt waagerechter wurf .. Es stimmt schon, dass es kompliziert werden kann, aber es ist durchaus möglich das ganze als Funktion darzustellen
stimmt, und dann berechne das mal für ein paar tausend bälle/partikel oder sonstwas, wo einem jede unnötige division so richtig weh tut. klar, man kann alles "richtig" und mit tausend integralen berechnen, die frage ist wohl nur, was der spieler dann von der dia-show hält ,-)
-
wie meinste das mit "integralen berechnen" ?
Sagen wir bei deinem verfahren steht sowas wiespeed = speed * 2;
speed fängt mit 1 hat und nach 4 steps haste dann einen speed von 32. Also würd bei dem "normalen" verfahren sowas wie
speed = 2^steps;
stehn. Ich seh jetzt aber nicht den Zusammenhang mit integralen oO
-
life schrieb:
wie meinste das mit "integralen berechnen" ?
Sagen wir bei deinem verfahren steht sowas wiespeed = speed * 2;
speed fängt mit 1 hat und nach 4 steps haste dann einen speed von 32. Also würd bei dem "normalen" verfahren sowas wie
speed = 2^steps;
stehn. Ich seh jetzt aber nicht den Zusammenhang mit integralen oO
wo kommen die denn her? wenn die geschwindigkeit in jedem schritt verdoppelt wird, dann ist nichtmal mehr die beschleunigung konstant.
dann so:
auto A fährt mit s kmh, seitenwind erzeugt eine beschleunigung von w m/s^2, die eigenbeschleunigung ist a und weil sich der bleifuß allmählich senkt steigt sie um "da" pro sekunde.
wenn die startposition p ist, wo ist die karre nach 5.63 sekunden?
und ist es jetzt angenehmer alle 1/25s die beschleunigung zu aktualisieren und beide beschleunigungen auf die geschwindigkeit zu addieren und letztere auf die position oder in jedem frame die mathematisch korrekte formel zu benutzen?
ein billiges 1/2 att + 1/2 wtt + vt (a,w,v vektoren)
klappt hier schon nicht mehr, weil a nicht konstant ist.physik ist vollgestopft mit integralen und die zu vermeiden ist sicher nicht die schlechteste idee.
-
das war nur ein einfaches beispiel an dem du mir die sache mit den integralen verdeutlichen solltest:
deswegen sind nicht lineare bewegungen mit der methode nur dann brauchbar, wenn man sie "sauber" berechnet (nur: will wirklich jemand mit integralen hantieren?)
-
Trienco schrieb:
nur: will wirklich jemand mit integralen hantieren?
für das einfache beispiel hier bin ich vor langer zeit mal bei sowas gelandet, um partikel im system auch "mittendrin" starten zu lassen:
pos+=(g*t*t)/2 + (vt);
v+=gt;Und was hindert dich daran, genau solche Formeln mit variablem t zu benutzen? Das kommt raus, wenn man über den Zeitschritt integriert. Ist also doch nicht so schwer, vor allem da es in jedem Physikbuch steht. Genau das gleiche muss man aber auch für einen festen Zeitschritt machen. Dann kann man evtl. noch einige Sachen vorher ausrechnen (z.b. t^2). Aber ansonsten ist kein großer Unterschied.
Bye, TGGC \-/
-
TGGC schrieb:
Und was hindert dich daran, genau solche Formeln mit variablem t zu benutzen?
die tatsache, daß nicht alle berechnung so simpel sind wie ein einfacher wurf.
und selbst so ein pos+=(v+=a) kommt ohne division aus.Genau das gleiche muss man aber auch für einen festen Zeitschritt machen. Dann kann man evtl. noch einige Sachen vorher ausrechnen (z.b. t^2). Aber ansonsten ist kein großer Unterschied.
eben nicht, man kann bei garantierten ausreichend kleinen schritten wie oben in diskreten schritten arbeiten, ohne große probleme zu bekommen.
aber der erwähnte link hat da einige kommentare, auch von professionellen entwicklern, die z.b. für irgendein nba spiel ziemlich genau das gleiche erst für variable schritte hatten und dann doch auf feste umgestellt haben.
beide methoden haben vor- und nachteile, aber so wie es in den kommentaren rauskommt sind feste schritte bei vielen bevorzugt.
-
eben nicht, man kann bei garantierten ausreichend kleinen schritten wie oben in diskreten schritten arbeiten, ohne große probleme zu bekommen.
Na und? Ich kann doch auch mit Variablen Zeitschritten dafür sorgen, das diese nie länger als x dauern.
Bye, TGGC \-/
-
TGGC schrieb:
Na und? Ich kann doch auch mit Variablen Zeitschritten dafür sorgen, das diese nie länger als x dauern.
wie? alles über x auf x zurechtschneiden oder in teilschritte zerlegen? dann sinds auch keine variablen schritte mehr, sondern irgendwo zwischen fest und variabel.
-
Trienco schrieb:
TGGC schrieb:
Na und? Ich kann doch auch mit Variablen Zeitschritten dafür sorgen, das diese nie länger als x dauern.
wie? alles über x auf x zurechtschneiden oder in teilschritte zerlegen? dann sinds auch keine variablen schritte mehr, sondern irgendwo zwischen fest und variabel.
Es gubt nihcts zwischen fest (konstant) oder variabel. Entweder es ist konstant oder nicht.
Bye, TGGC \-/
-
TGGC schrieb:
Es gubt nihcts zwischen fest (konstant) oder variabel. Entweder es ist konstant oder nicht.
das ist aber haarspalterei, wenn man mal variable schritte benutzt und dann mal wieder feste, wie soll man es dann insgesamt nennen, wenn nicht "irgendwo dazwischen"?
-
dann sind die werte allesamt variabel.