Entwickler-Ecke

Grafische Benutzeroberflächen (VCL & FireMonkey) - Formel für die Kraft


mg4all - Fr 21.01.11 09:18
Titel: Formel für die Kraft
Hallo Leute.

Ich suche eine Formel mit der ich die Kraft des Schusses berechnen kann, um den Gegner zu treffen (KI).
Ich habe die Distanz zwischen zwei Körpern :


Delphi-Quelltext
1:
distance := round(sqrt(power((xcoord - image2.Left), 2) + power((ycoord - image2.Top), 2)));                    


Mit diesem Timer ist es kein Problem, da ich die kraft vorgebe !


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
procedure TForm1.Timer1Timer(Sender: TObject);
begin
 zeit:=zeit+0.08;
 x := Round(startx + (kraft * cos(swinkel) * zeit + wind *zeit * zeit * 0.3));
 y := Round(starty - (kraft * sin(swinkel) * zeit - 0.5 * 9.81 * zeit * zeit));
 image2.Left := x;
 image2.top := y;
if (image2.Top + (image2.Height div 2)) > 600 then
 begin
 image2.Top := 296;
 image2.Left := 672;
 timer1.Enabled := false;
 end;
end;


Wie kann ich das aber umgedreht bewerkstelligen, wenn ich die Kraft berechnen will um den Gegner zu treffen?


Martok - Fr 21.01.11 10:05

Ballistik 101: der schräge Wurf.
Was du da vorgibst, ist nicht die Kraft, sondern die Ausgangsgeschwindigkeit. Also Gleichung aufstellen für y(x), Umstellen nach v0(y:=0,x:=xgegner), fertig. Das einzige Problem hier dürfte wohl der Gegenwind sein, da werden die Gleichungen etwas hässlich.
Als Winkel nimmt man dann meistens 45° an, da fliegt der Schuss am weitesten mit der niedrigsten v0.


mg4all - Sa 22.01.11 08:27

Danke user profile iconMartok für deine Antwort.

Ich bin leider kein Mathe-Genie und bekomme meine Formeln für X und Y nicht so richtig umgestellt! (eigentlich gar nicht) :oops:
Kannst du mir vielleicht ein bischen auf die Sprünge helfen ? :?:
Oder kann ich das irgendwo nachlesen, da ich es ja auch nachvollziehen möchte !

Ich hatte mir die Lösung so gedacht :


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
procedure TForm1.Button2Click(Sender: TObject);
begin
startx := image2.Left;
starty := image2.Top;
x := image2.Left;
y := image2.Top;
zeit := 0;
for kraft := 0 to 400 -1 do
 begin
 x := Round(startx + (kraft * cos(swinkel) * zeit + wind *zeit * zeit * 0.3));
 y := Round(starty - (kraft * sin(swinkel) * zeit - 0.5 * 9.81 * zeit * zeit));
 zeit:=zeit+0.08;
 if (x < image1.left + image1.Width) and (y < image1.Top + image1.Height) then break;
 end;
 label1.Caption := inttostr(kraft);
 label2.Caption := floattostr(y);
end;


Leider ging das natürlich total in die Hose :evil: :evil: :evil:


Martok - Sa 22.01.11 14:25

Also ich hatte das mal irgendwann 10.Klasse Physik machen müssen. Eine Seite A4 ungefähr, aber nur weil ich mich irgendwo verzettelt hatte. Ich guck mal, ob das nochmal was wird.
EDIT: ein Genie muss man dafür aber nicht seinm, da ist eigentlich nix esoterisches dabei.

Deine Idee ist ziemlich kreativ, aber durchaus legitim, nur 2 Fehler: swinkel wird nicht festgelegt, und du brauchtst natürlich 2 Schleifen: eine, die einen Schuss durchführt, und eine die neue v0 generiert. Und die Compilerwarnung was das Verwenden der Variable nach Schleifenende angeht sollte man beachten ;)


EDIT2: okay der Wind bei dir macht die Sache echt unschön, das werden ganz schön viele Wurzeln. Wenn du was selber erfinden willst, mach doch lieber deine numerische Variante, aber halt richtig. Ansonsten beliebiges CAS lösen lassen, von Hand würd ich das nicht machen wenn man nicht unbedingt muss. Intervallsuche bietet sich hier an, also sowas in der Art:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
v0=0;
swinkel=45°;
schritt=1;
SOLANGE schritt>schritt_grenze TUE
  Simuliere Schuss bis Y>YStart (* Bis Schuss wieder auf Boden *)
  ?Zu weit
    v0=v0-schritt;
    schritt=Schritt/2;
  Sonst
    ?Zu kurz
      v0=v0+schritt;
    Sonst
      v0 übernehmen  (* getroffen *)
      Schleife verlassen

Danach müsste v0 stimmen: entweder wir haben genau getroffen, oder abgebrochen wegen Schrittweite an Untergrenze. Wenn dann immer noch daneben war, ist das Ziel nicht treffbar.


mg4all - So 23.01.11 09:37

Danke user profile iconMartok für deine schnelle Hilfe. Ich verstehe was du meinst kann es aber in Delphi nicht umsetzen !!! :oops:

Der swinkel wird beim Aufruf angegeben : 110° ! (also nach links)

Ich habe es so probiert :


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:
procedure TForm1.Button2Click(Sender: TObject);
var kraft: integer;
begin
zeit := 0;
startx := image2.Left;
starty := image2.Top;
x := image2.Left;
y := image2.Top;
for kraft := 1 to 400 -1 do
 begin
 zeit:=zeit+0.08;
 y := Round(starty - (kraft * sin(swinkel) * zeit - 0.5 * 9.81 * zeit * zeit));
 if y < image1.Top then
  begin
   x := Round(startx + (kraft * cos(swinkel) * zeit + wind *zeit * zeit * 0.3));
   y := Round(starty - (kraft * sin(swinkel) * zeit - 0.5 * 9.81 * zeit * zeit));
   zeit:=zeit+0.08;
  end;
 if (x >= image1.left) and (x <= (image1.Left + image1.Width)) then
  begin
   abschuss := kraft;
  end;
 end;
 label1.Caption := inttostr(abschuss);
 label2.Caption := floattostr(y);
end;


Ich hänge mal den kompletten Quellcode an, damit du mein Project verstehst! :D


Martok - So 23.01.11 18:45

user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:
Ich verstehe was du meinst kann es aber in Delphi nicht umsetzen !!! :oops:
Merkt man, da ist eigentlich gar nix drin von dem was ich geschrieben hab...


user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:
Ich hänge mal den kompletten Quellcode an, damit du mein Project verstehst! :D
Ich guck mir das mal an. Schöne Grüße an user profile icondummzeuch, erstmal den Code lesbar gemacht :shock:

Dein Wald aus globalen Variablen macht das nur nicht grade einfacher, und Fehler sind da eigentlich vorprogrammiert. Na mal sehen ;)


delfiphan - So 23.01.11 19:19

Die Formel ist x=vt+0.5at^2+x0, wobei alles ausser t Vektoren sind. Dein v setzt sich zusammen aus vWind + vInitial und dein a ist -g*êy (d.h. -g nach unten).


Martok - So 23.01.11 19:45

Theoretisch ja, praktisch hat er das physikalisch nicht ganz korrekt gemacht. Oder ich brauch Urlaub, das kann auch sein...

Außerdem gibts hier mehr zu lernen bei ;)

Angehängt eine Implementation von dem was ich weiter oben schrieb (so ungefähr). Ziemlich heftig kommentiert, sollte also verständlich sein.
Ich hab allerdings keinen der grundlegenden Fehler behoben, das müsstest du noch tun. Beziehungsweise das ganze neu machen: Globale Variablen, Code-Wiederholung und Datenhaltung in Steuerelementen mal so als Stichworte.


mg4all - Di 25.01.11 08:23

Hallo user profile iconMartok :D

Vielen Dank für deine Hilfe, ich glaube jetzt habe ich es auch halbwegs verstanden. Was mich aber noch ein bischen irritiert ist :


Delphi-Quelltext
1:
schritt := 50;                    

Warum fängst du ausgerechnet mit 50 an ?

Und noch eine Frage : Da mein Maximum nicht 400 überschreiten darf, wo kann ich das berücksichtigen ?

Hab wirklich vielen Dank für deine Hilfe, ich stand völlig auf dem Schlauch !!! :oops:

PS : Hast du dir mal die Bilder angesehen ??? :?:

Und wo kann ich dir ein Danke mehr geben, hab das Forum noch nicht ganz durschaut :?: :?: :?:


Martok - Di 25.01.11 09:56

user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:

Delphi-Quelltext
1:
schritt := 50;                    

Warum fängst du ausgerechnet mit 50 an ?
Ausprobiert: mit kleineren Werten hats zu lange gedauert ;) Da das erste Ziel was ich probiert hab immer so zwischen 50 und 100 lag, hat sich das angeboten im ersten Schritt gleich die 50 zu überspringen. Wären halt sonst ein paar Iterationen mehr.


user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:
Und noch eine Frage : Da mein Maximum nicht 400 überschreiten darf, wo kann ich das berücksichtigen ?
Das von der Geschwindigkeit? Das wäre dann wohl eine zusätzliche Bedingung für die äußere Schleife, also while (schritt>schritt_grenze) and (v0<400) do. Dann kannst du nach der Schleife prüfen, ob was gefunden wurde (abschuss<>0). Wenn nicht, dann Fehler.


user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:
PS : Hast du dir mal die Bilder angesehen ??? :?:

Lustich? :P

user profile iconmg4all hat folgendes geschrieben Zum zitierten Posting springen:
Und wo kann ich dir ein Danke mehr geben, hab das Forum noch nicht ganz durschaut :?: :?: :?:
Unter dem Beitrag, in der Zeile wo auch PN und sowas steht. Ganz rechts - falls du Ajax in den Erweiterten Einstellungen aktiv hast.