Vektorrechnung und Gleichungs-Systeme kleiner Erfolg

Übersicht BlitzBasic Allgemein

Neue Antwort erstellen

Kabelbinder

Sieger des WM-Contest 2006

Betreff: Vektorrechnung und Gleichungs-Systeme kleiner Erfolg

BeitragSo, Jul 15, 2007 21:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo

Ich stehe vor einem Problem. Vielleicht kann mir dabei jemand helfen, der Ahnung von Gleichungssystemen und Vektorrechungn hat.
Seit langem schon überlege ich daran, wie man den Abschusswinkel berechnen kann, den man benötigt, um ein bewegtes Ziel bei konstanter Geschwindigkeit von Ziel und Projektil zu treffen; denn wenn man genau auf das Ziel zielt, hat es sich ja vielleicht schon wegbewegt, sobalt das Geschoss an der Stelle ankommt (und das gerade ist die Schwäche vieler Computerspiel KIs).

Ich habe überlegt, dass man das vielleicht mit Vektorrechnung hinbekommen könnte. man beschreibt einfach zwei Geraden:
Einmal die Gerade, auf der das Ziel fliegt und einmal die Gerade, die das Geschoss nachher fliegt.

Das besondere dabei ist, dass beide Geraden den gleichen Parameter A haben. A Steht also für die Schritte, nachdem das Geschoss das Ziel trifft.

Es müsste also gelten:
Code: [AUSKLAPPEN]
(cx)       (ex)             (px)       (rx)
(cy) + A * (ey) * speed  =  (py) + A * (ry)


cx und cy sind die Koordinaten der Kanone, aus der geschossen wird (Stützvektor).
ex und ey sind die Kompnenten (x,y) des Einheitsvektors, der die Richtung angibt, in die geschossen wird.
speed ist die Geschwindigkeit, mit dem das Geschoss fliegen wird (Einheitsvektor * Länge = Richtungsvektor). Natürlich muss diese Geschwindigkeit konstant sein, man kann schließlich nicht z.B. einmal mit 2 und einmal mit 4 Pixeln pro Umlauf schießen.

px und py sind die aktuellen Koordinaten des Ziels, im Moment, in dem geschossen wird (Stützvektor).
rx und ry sind die Kompenenten (x,y) des Richtungsvektors des Ziels
A steht wie gesagt für die Durchläufe bis zur Kollision.

So, wer sich mit Vektorrechnung auskennt, hat's bis hierher wahrscheinlich verstanden.


nun hat man ja folgende Bekannte:
cx,cy,speed,px,py,rx,ry

und folgende Unbekannte:
A : Man weiß nicht, wieviele Durchläufe man bei der vorgegebenen Geschwindigkeit braucht.
ex, ey : Man weiß nicht, in welche Richtung man schließlich schießen muss.

Zudem weiß man noch, dass es sich bei
Code: [AUSKLAPPEN]
(ex)
(ey)
dem gesuchten Vektor um einen Einheitsvektor handelt, also gilt auch noch folgendes:
Code: [AUSKLAPPEN]
ex²+ey² = 1


Somit kommt man auf diese Gleichungssysteme:
Code: [AUSKLAPPEN]
I  |cx+speed*ex*A = px+rx*A|
II |cy+speed*ey*A = py+ry*A|
III|ex²+ey² = 1            |


Ich habe hier man einfach drauf los gerechnet:
1) I nach ex umgestellt
2) II nach ey umgestellt
3) III nach ex umgestellt
4) I und III über ex gleichgesetzt, und IV erhalten
5) IV nach ey umgestellt
6) II und IV über ey gleichgesetzt: A ist der einzige Unbekannte.

Doch ich bin bei bestem Willen nicht in der Lage, diese Gleichung und A umzustellen (Sie ist auch zu kompliziert, um sie zu posten).
kann das jemand?
hätte ich anders vorgehen sollen? Können?

Übrigens ist es leicht, dass Ziel zu treffen, wenn man Geschwindigkeit und Durchläufe bis zum Einschlag frei wählen kann. Das ist aber unsportlich Smile .
<Wing Avenger Download> ◊◊◊ <Macrophage Download>
  • Zuletzt bearbeitet von Kabelbinder am Do, Jul 19, 2007 20:03, insgesamt einmal bearbeitet

Kabelbinder

Sieger des WM-Contest 2006

BeitragDo, Jul 19, 2007 20:03
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab es nun doch geschafft, die Gleichung nach A umzustellen Laughing .
Scheint auch mehr oder weniger zu funtionieren, nur leider sind die Floats in BB nicht genau genug. Das Geschoss verfehlt of schonmal sein Ziel.
Obwohl das Mathematisch stimmt...

Man bekommt als Gleichung mit A als Variable eine quadratische Gleichung raus. Wenn die Gleichung keine Lösung hat, ist das Geschoss nicht schnell genug, um das Ziel, das sich wegbewegt noch zu treffen. Bei zwei Lösungen bin ich nicht sicher, welche ich nehmen sol...

Ich weiß nicht, ob ich die Ergebnisse posten soll... Confused
<Wing Avenger Download> ◊◊◊ <Macrophage Download>
 

Krümel

BeitragFr, Jul 20, 2007 19:14
Antworten mit Zitat
Benutzer-Profile anzeigen
das Ergebnis würd mich schon interessieren, also immer her damit Laughing

Kabelbinder

Sieger des WM-Contest 2006

BeitragDi, Jul 31, 2007 22:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Sorry, dass es so lang gedauert hat, ich bin heute erst aus'm Urlaub zurückgekommen.

Ich hab's jetzt nochmal gerechnet, weil ich keinen Bock hatte, meine alten Aufzeichnungen abzuschreiben:

Code: [AUSKLAPPEN]
0) Ausgangs-System
 I  |cx + A * ex * speed = px + A * rx|
 II |cy + A * ey * speed = py + A * ry|
 III|ex² + ey²           = 1²

1) III umstellen:
 III|ex² = 1² - ey²|

2) I nach ex umstellen:
 I  |ex = (px-cx + A*rx) / (A*speed)|

3) II nach ey umstellen:
 I  |ey = (py-cy + A*ry) / (A*speed)|

4) in III einsetzen:
 IV |((px-cx + A*rx) / (A*speed))²  = 1² - ((py-cy + A*ry) / (A*speed))²| * (A*speed)²

 IV |(px-cx + A*rx)²  = (A*speed)² - (py-cy + A*ry)²|

5) Klammern auflösen:
5a) , 3. Bin Formel:
     IV |(px-cx + A*rx)²  =                                     
hier     (A*speed + (py-cy + A*ry)) * (A*speed - (py-cy + A*ry))|

5b) , mit sich selbst multiplizieren:
hier IV |(px-cx + A*rx) * (px-cx + A*rx)  =                     
        |(A*speed + (py-cy + A*ry)) * (A*speed - (py-cy + A*ry))|

5c) , weg mit den inneren klammern:
     IV |(px-cx + A*rx) * (px-cx + A*rx)  =                 
hier     (A*speed + py-cy + A*ry) * (A*speed -py+cy - A*ry)|

So, un nu jeht dat Jerechne los:


Ich hab raus:
 IV |px² - 2*px*cx + 2*px*A*rx + cx² - 2*cx*A*rx + (A*rx)² =
     (A*speed)² - py² + 2*py*cy - 2*py*A*ry - cy² - 2*cy*A*ry - (A*ry)²|

puh...

diese Formel nach 0 umgestellt:

px²+py² - 2*px*cx-2*py*cy + 2*px*A*rx+2*py*A*ry+ cx²+cy²- 2*cx*A*rx+2*cy*A*ry + 2A²*rx² - A²*speed² = 0

A möglichst oft ausklammern:

 A²(2*rx² - speed²) A*(2*px*rx+2*py*ry - 2*cx*rx+2*cy*ry) + px²+py² - 2*px*cx-2*py*cy + cx²+cy² = 0

Quadratisch

mit p = (2*px*rx+2*py*ry - 2*cx*rx+2*cy*ry) / (2*rx² - speed²)
und q = (px²+py² - 2*px*cx-2*py*cy + cx²+cy²) / (2*rx² - speed²)

das muss man dann nurnoch in die p-q Formel einsetzen und sich für eins der Beiden Ergebnissse,

(+ oder - entscheiden)

mit A kann man dann ex und ey berechnen

ich komme tatsächlich nur auch Werte unter 1 muss also was wahrer dran sein


Jedenfalls so inetwa

Ich hab da mal was vorbereitet:
Code: [AUSKLAPPEN]
AppTitle "Bewegtes Ziel"
Graphics 640,480,16,2
SeedRnd MilliSecs()

Const max = 9
Const bmax = 30
Const speed# = 4.7

Global cx#,cy#,num,rot#,bnum,shoottimer,ex#,ey#,ziel,lan#,lamda#,p#,q#,nicht

Dim obj#(max,5)
Dim bullet#(bmax,5)

Function create(x,y,xr#,yr#)
obj(num,3)=1
obj(num,1)=x
obj(num,2)=y
obj(num,4)=xr#
obj(num,5)=yr#
If num<max Then num = num + 1
End Function

Function edit()
For i = 0 To max
If obj(i,3)=1 Then
obj(i,1)=obj(i,1)+obj(i,4)
obj(i,2)=obj(i,2)+obj(i,5)
If obj(i,1)>640 Then obj(i,1)=0
If obj(i,1)<0 Then obj(i,1)=640
If obj(i,2)>480 Then obj(i,2)=0
If obj(i,2)<0 Then obj(i,2)=480
EndIf
Next
End Function

Function shoot(x,y,xr#,yr#)
bullet(bnum,3)=1
bullet(bnum,1)=x
bullet(bnum,2)=y
bullet(bnum,4)=xr
bullet(bnum,5)=yr
If bnum = bmax Then
bnum = 0
Else
bnum = bnum + 1
EndIf
End Function

Function zisch()
For i = 0 To bmax
If bullet(i,3)=1 Then
bullet(i,1)=bullet(i,1)+bullet(i,4)
bullet(i,2)=bullet(i,2)+bullet(i,5)
If bullet(i,1)>640 Then bullet(i,3)=0
If bullet(i,1)<0 Then bullet(i,3)=0
If bullet(i,2)>480 Then bullet(i,3)=0
If bullet(i,2)<0 Then bullet(i,3)=0
EndIf
Next
End Function

Function kollision()
For i = 0 To max
For j = 0 To bmax
If obj(i,3)=1 And bullet(j,3)=1 Then
If RectsOverlap(obj(i,1)-5,obj(i,2)-3,7,7,bullet(j,1)-4,bullet(j,2)-7,9,9) Then
obj(i,3)=0
bullet(j,3)=0
EndIf
EndIf
Next
Next
End Function

Function zielen()
If MilliSecs()-shoottimer>4000
shoottimer = MilliSecs()

If ziel = max Then
ziel = 0
Else
Repeat
ziel = ziel + 1
If ziel = max Then Exit
Until obj(ziel,3)=1
EndIf

px# = obj(ziel,1)
py# = obj(ziel,2)
rx# = obj(ziel,4)
ry# = obj(ziel,5)

p# = (-2.0*px*rx-2.0*py*ry+2.0*cx*rx+2.0*cy*ry)/(speed-rx^2.0-ry^2.0)
q# = (-px^2.0-py^2.0+2.0*cx*px+2.0*cy*py-cx^2.0-cy^2.0)/(speed-rx^2.0-ry^2.0)
nicht = ((p/2.0)^2.0-q)<0

If nicht = 0 Then
lamda = -p/2.0+Sqr((p/2.0)^2.0-q)

ex = (px+lamda*rx-cx)/(lamda*speed)
ey = (py+lamda*ry-cy)/(lamda*speed)

rot = ATan2#(ey,ex)
shoot(cx,cy,ex,ey)
Else
shoottimer = 0
EndIf

EndIf
End Function

Function draw()
For i = 0 To max
If obj(i,3)=1 Then
Color Cos(i*18)*255,Sin(i*18)*255,(1/Tan(i*18))*255
Rect obj(i,1)-3,obj(i,2)-3,5,5
EndIf
Next

Color 0,255,255
Line cx,cy,cx+Cos(rot)*10,cy+Sin(rot)*15

Color 255,0,0
For i = 0 To bmax
If bullet(i,3)=1 Then
Rect bullet(i,1)-2,bullet(i,2)-2,3,3
EndIf
Next

Color 100,0,100
Line cx,cy,obj(ziel,1),obj(ziel,2)

Color 255,255,255
If nicht = 1 Then Text 0,0,"Nicht möglich"

Text 0,30,ex
Text 0,40,ey
End Function

For i = 0 To max
roll# = Rnd(0,360)
create(Rand(100,540),Rand(100,380),Cos(roll)*Rnd(0.2,1.1),Sin(roll)*Rnd(0.2,1.1))
Next
cx = 320
cy = 240
num = 0

shoottimer = MilliSecs()
Repeat
fratim = MilliSecs()

zielen()
edit()
zisch()
kollision()
draw()

Flip
If MilliSecs()-fratim>13 Then Delay 13-(MilliSecs()-fratim)
Cls
Until KeyHit(1)
End


Funktioniert nur leider kaum... Vielleicht verrechnet. Aber ich glaube, BB ist einfach nicht genau genug.
<Wing Avenger Download> ◊◊◊ <Macrophage Download>

Neue Antwort erstellen


Übersicht BlitzBasic Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group