"Sanft" beschleunigen und abbremsen...
-
Hi,
ich will einen Gegenstand von a nach b bewegen (nur auf der X-Achse), wie krieg ich das so hin, dass der Gegenstand sanft beschleunigt und vor dem Ziel wieder sanft abbremst? Also soll nicht so eine Ruckartige bewegung sein, halt bei Punkt A ist die x Geschwindigkeit = 3 und bei b wieder 0, soll schön gut aussehen...
Danke,
TheToast
-
naja also
-
hmm da hab ich wohl was gemacht was ich nicht wollte... sorry
-
wie wärs mit
sin(aktuelle_teilstrecke/gesamtstrecke * pi) * max_speed
-
ehm wenn du jetzt pi mit 90grad austauscht dann macht es auch sinn..
sollt mich ma registrieren zwecks edit..
-
Wieso nicht einfach konstant beschleunigen/abbremsen? In der Bewegung gibt es da keinen Ruck.
-
Klingelmann: Sieht nicht so gut aus
Defob: Ich glaub, das ist das, was ich gesucht hab, danke, ich probiers aus...
-
Hallo,
in DarkBasic ging das ungefähr so:DO
If Upkey()=1 then a=timer() : boost=1
t=(timer()-a)If t < 3000 then speed#=speed#+0.3
If t > 3000 and boost=1 then speed#=speed#+1move object 1, speed#
LoopIch hoffe du kannst das umsetzen
cu max
-
Ich weiß nicht, ob sin so gut aussieht ... wenn die Gesamtstrecke länger wird, wird ja die Anfangsgeschwindigkeit kleiner. Genauso die Bremsphase. Das sieht dann so bouncy aus irgendwie.
Du musst dich zunächst entscheiden, welche Wegableitungen du begrenzen willst. Wie mein ich das? Ich mal ein ein Nonsensbeispiel am Anfang zur Veranschaulichung. Angenommen, die Geschwindigkeit wär unbegrenzt. Dann könntest du direkt in 0 Zeit an den Endpunkt springen. Unfug, offensichtlich.
Also begrenzen wir die Geschwindigkeit und lassen die Beschleunigung (2. Wegableitung) unbegrenzt. Auch doof.
Die Beschleunigung sollte also auch begrenzt sein. Die dritte Wegableitung, der Ruck, muss nicht unbedingt begrenzt werden (jedenfalls nicht solange du keine Passagiere beförderst *g*). Kann man machen, dann wirds noch ein wenig komplizierter. Wir haben jetzt folgende Vorgänge hintereinander:
* Beschleunigung a springt auf a_0
* Geschwindigkeit v steigt mit a_0 * t bis zur maximalen Geschwindigkeit v_0, bleibt dann konstant
* zurückgelegter Weg s steigt mit 1/2 a_0 * t^2
* irgendwann alles rückwärts (wobei die Bremsbeschleunigung anders sein kann als a_0)
Wenn der Ruck begrenzt ist, springt dieser anfangs auf r_0, a steigt linear an, v quadratisch, s kubisch ... theoretisch könnte man noch höhere Wegableitungen begrenzen, aber praktisch macht man das AFAIK nicht.
Man muss natürlich vorher berechnen, ab welcher Stelle man wieder bremst. Macht man das alles, hat man am Ende einen zeitoptimalen Bewegungsablauf*. Aufpassen muss man, wenn der Weg so kurz ist, dass die Beschleunigungsphase zum Umkehrzeitpunkt noch nicht zuende ist.Das wirst du so wahrscheinlich nicht umsetzen wollen, aber es sollte dir eine Idee geben. Wenn a_0 relativ klein ist, die Beschleunigungsphase also recht lang, dürfte das nicht so übel aussehen. Kannst auch mit der Ruckbegrenzung experimentieren, vielleicht bringt das was.
es gibt auch energieoptimale Bewegungen, da hab ich aber die Berechnung nicht im Kopf
-
Dioe Frage interessiert mich.
ich hab mal zur rein mathematischen Behandlung des Problems einen neuen Thread aufgemacht:
http://www.c-plusplus.net/forum/viewtopic.php?t=58949
Hier geht es ja wohl mehr um eine passable Implementierung für grafische Darstellung. Da ist der Aspekt der optimalen Zeit ja nicht mit drin.
-
If Upkey()=1 then a=timer()//nimm so etwas wie getticcount und fütter damit eine Variable : boost=1 //mach stattdessen eine integer Variable t=(timer()-a) //erstelle eine Variable in der du einen Neuen Timer einbringst, //der -a gerechnet wird If t < 3000 then speed#=speed#+0.3 //Wenn t <3000 also 3 Sekunden lang gedrückt dann mache das dass auto schneller wird. If t > 3000 and boost=1 then speed#=speed#+1 move object 1, speed#
Mathematisch gesehen:
Ein Timer der bei dem drücken der Taste erstellt wird, wird gegen einen allgemein laufenden Timer gerechnet, wenn der Timer einen bestimmten wert erreicht, beschleunigt das Auto. Mache Recht viele Stufen an Beschleunigung und
das ding beschleunigt ziemlich echt.Ich bin mir nicht sicher, aber das müsste so gehen.
cu max
-
Wenn du die Sinus Funktion benutzt wird die Bewegung ähnlich aussehen wie bei einem Pendel.
Wenn man das loslässt beschleunigt es erst langsam, dann immer schneller, wird dann wieder langsamer und kommt ganz zum Stillstand. Dann geht es wieder von vorne los.Sollte dann aber mehr so aussehen:
aktuelle_position=(cos(aktueller_zeitpunkt/gesamte_Dauer_der_Bewegung * pi)+1) * gesamte_Strecke/4 if(aktueller_zeitpunkt/gesamte_Dauer_der_Bewegung > 0.5) aktuelle_position=gesamte_Strecke-aktuelle_position
-
Soll nur gut aussehen, ob der jetzt 2 Zehntel Sekunden eher da ist, ist egal...
Sowas ist schon ganz gut, aber wozu ist das "* gesamte_Strecke/4" gut?