ATan2 richtig nutzen?
Übersicht

PhillipKBetreff: ATan2 richtig nutzen? |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Heyho Leute ![]() Ich versuche mich grade an einem BCC betriag und möchte dafür eine simple KI implementieren. Da es ein bcc beitrag ist, werde ich nicht allzuviel verraten können ![]() Allerdings erwarte ich auch keine genaue hilfe, sondern nur eine erklärung zu ATan2 - ich kriegs nämlich irgendwie nicht hin ![]() Sinn des ganzen ist, das ich einen Punkt(x,y koordinate) anpeilen möchte. Dh meine Ki hat ihren Punkt XY und den Wunschpunkt XY Bisher konnte ich ATan2 immer ohne große probleme nutzen. Allerdings kann ich es nicht zulassen, das sie sich auf der stelle dreht, der winkel muss sich "annähern" - und hier passiert nur murks ![]() Ich brauche das ganze an 2 Stellen - einmal zum groben anpeilen und einmal zum groben weg-peilen ![]() Das eine versucht also auf einen punkt zuzusteuern, das andere versucht, davon wegzusteuern. Damit das ganze aber keine Cheatki wird, muss die maximale Winkelveränderung den möglichkeiten des spielers entsprechen. BlitzMax: [AUSKLAPPEN] Self.angle:+(angle2 * 0.20) Das ist mein versuch, des Davon-weg-peilen. An sich klappts super,ausser wenn mein punkt Rechts liegt. KI ------> Punkt x=10 x = 100 y ist irrelevant, sobald es nur ansatzweise auf 0° (glaube ich? ^^) liegt, gibts in sofern murks, das die KI nicht wie gewohnt davon weg, sondern EXAKT drauf zu steuert. Das ganze ist ziemlich experimentell, hab hier unmengen an varianationen durchgetest. Angefangen von differenzveränderung, direktem draufaddieren /direktem setzen, Atan2() + 180, Atan2()-180, Atan2()+90 ... Ich befürchte also, ich habe ATan2 nicht wirklich verstanden. ------------------------------- Hier nun endlich mal meine frage: WIE nutze ich Atan2? Die parameter sind y,x Angaben tue ich: Atan2( Wunsch.Y - KI.Y, Wunsch.X - KI.X ) Meines wissens nach, gibt ATan2 den absoluten winkel, aber irgendwas scheint da noch murks zu sein. (Die richtung meiner KI war beispielsweise 30°, der Wunschpunkt lag direkt vor ihr und der winkel war -13°? oO) Ich hoffe, ihr könnt mir diesen kleinen kieselstein in meinem Programmierfluss bereinigen. PS: Meinen BCC beitrag werde ich ohne fremde Hilfe schreiben. Geht immerhin um die ehre ![]() ![]() ![]() Gruß, Phillipk ![]() |
||
![]() |
ZEVS |
![]() Antworten mit Zitat ![]() |
---|---|---|
Mir fallen spontan zwei Lösungen ein:
1. Du errechnest, in welche Richtung gedreht werden soll und drehst dann entsprechend. Das Problem mit 0°-360° kannst du umgehen, indem du einfach alle Winkel vor der Berechnung +360° nimmst und danach wieder in einen Raum zwischen 0° und 360° bringst. 2. Du suchst dir irgendeinen Punkt, der in gerader Linie vor deiner KI liegt. Von dort aus gehst du ein Stück zum Wunschpunkt und berechnest dahin den Winkel. Ich hoffe, ich konnte dir soweit helfen |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Nicht so ganz ![]() Ich habe das gefühl, nur geglaubt zu haben, wie ATan2() funktioniert. Früher und in diesem projekt hat es öfters anwendung gefunden, wenn es darum ging, einen winkel von punkt XY auf punkt AB auszurichten. Hat immer geklappt. Nur wenn ich versuche, eine differenz zwischen dem momentanen winkel (a) zu dem gewünschten winkel (b) auszurechnen und nur einen teil davon auf a zu addieren, geschieht nur murcks. ![]() Hier mal eine kleine bebilderung. Das problem ist, die funktion an sich funktioniert. Allerdings wenn ausrichtung und Vermeidungspunkt auf der rechten seite liegen, ich vermute, wenn sie beide um 0° +/-10 liegen (eins drüber, eins drunter), dann funktioniert es nichtmehr. Dann passiert das gegenstück: Statt den punkt zu vermeiden wird er voll angepeilt. Ich vermute, wie schon erwähnt, das ich nicht genau verstehe, wie ATan2() funktioniert. Wenn ich es richtig gelesen habe, ist nach 'rechts' 0° - dh 0 und 360°. Liegt der mit atan2 angepeilte punkt nun über dieser 0° linie, wird diese negativ und spuckt zb -15° aus, wo ich in meiner jetzigen rechnung eigentlich (360-15)° erwarten würde. und einfach hier oder da mal 180° addieren geht auch nicht, da es dann zwar für rechts klappen sollte aber nichtmehr für oben,unten und links ![]() PS: Anwendungsgebiet findet sich in positionserrechnung per Sin und Cos, sowie in der funktion glRotated() - ich verschiebe meine KI immer um ihren sin und cos wert in richtung winkel#, drehe die grafiken anhand dieser etc. Trifft sie nun auf einen punkt, den sie vermeiden soll, darf sie aber der fairnesshalber nicht direkt zum nächsten erlaubten punkt springen, sondern muss sich diesem mit einer ähnlichen geschwindigkeit wie die vom spieler annähern! ![]() |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
BlitzMax: [AUSKLAPPEN] Graphics 400,300 Bei Additionen von Winkel das ganze immer mit einem abschließenden... BlitzMax: [AUSKLAPPEN] Wert= (Wert + 360 ) Mod 360 ...behandeln |
||
![]() |
HolzchopfMeisterpacker |
![]() Antworten mit Zitat ![]() |
---|---|---|
Ich weiss nicht, ob ich dich richtig verstehe... Du hast zwei Punkte? Einen Anpeil- und einen Meid-Punkt? ![]() Nun denn, zu etwas ganz anderem: Wenn man sich in kleinen Schritten in eine bestimmte Richtung drehen will, wählt man ja intuitiv den kürzeren Winkel. Wer will sich schon von 0° auf 355° um 355° drehen? ![]() 1. Man rechnet die normale Winkeldifferenz, dies ergibt i.d.R. etwas zwischen -360° und +360° 2. Mit dieser Formel schränkt man den Bereich (logisch) auf -180° bis +180° ein: BlitzMax: [AUSKLAPPEN] winkeldifferenz = ATan2(Sin(winkeldifferenz),Cos(winkeldifferenz)) Anwendungsbeispiel: BlitzMax: [AUSKLAPPEN] SuperStrict mfG Holzchopf |
||
Erledige alles Schritt um Schritt - erledige alles. - Holzchopf
CC BY ♫ BinaryBorn - Yogurt ♫ (31.10.2018) Im Kopf da knackt's und knistert's sturm - 's ist kein Gedanke, nur ein Wurm |
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Ich werd eure beiden programme gleich einmal austesten ![]() Komme grade von streichen, deswegen war ich etwas abwesend *g* Zu den Punkten: Nein, ich habe eigentlich 2 Probleme die sich wahrscheinlich beide auf falschen umgang mit ATan2 beschränken. Das größere und "sichtbarerere" problem ist auf jedenfall der Meidpunkt. Evtl könnte die logische änderung des Winkels schon helfen, da werd ich besonders aufmerksam durchgucken ![]() Das ding ist, ich habe nie eine KI geschrieben. Allerdings möchte ich auch keine riesen wegpunkt struktur schreiben, da das wahrscheinlich die leistung arg drücken würde. Da sowieso immer alles irgendwie erreichbar sein wird, werde ich einen anderen weg wählen: Hindernisse umgehen. Die idee ist, sobald ein hinderniss (meid-punkt) gefunden wurde, soll eine drehung davon weg stattfinden. Nur um einen solchen wert, dass das hinderniss sauber umgangen wird und das ganze auch nicht zu ruckartig stattfindet. Je nachdem wie es mit den eigentlichen spielinhalten aussieht, werde ich dann evtl dochnoch ein minimalistisches wegpunktsystem einbauen. Aber da ich auf jedenfall eine KI brauche um meinen BCC beitrag zu präsentieren, braucht es ein mindestmaß an nicht-doofheit ![]() Gut. Erstmal: Kaffe, calm down & dann ne runde programme durchlesen ![]() -------- Mir ist grade etwas eingefallen: Da der meid-punkt nicht unmittelbar auf dem eigentlichen soll-punkt liegt, habe ich immer versucht, von dem meidpunkt zum eigentlichen winkel eine differenz zu bilden und mich anhand dieser noch weiter vom Meid-punkt weg zu bewegen (zu einem Unbestimmten neuen Soll-punkt - hauptsache weg!) Meinen fehler habe ich bis jetzt nur am rechten rand festgestellt. Teilweise, wenn mein winkel sehr steil zur wand war, gings. Vielleicht hab ich genau den sonderfall erwischt, das Meid-punkt und soll-punkt exakt im selben winkel zum Ist-punkt standen, das keine differenz zu bilden war (ergebnis 0) und somit kein ausweichschritt vorgenommen wurde. Ich werde das ganze mal, nach konsultieren der Programme, mal genauer unter die lupe nehmen. Diese idee kam mir nämlich einfacht nicht oÔ |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Heyho ich melde mich mal wieder ![]() Mein ATan2 problem hatte ich bisher aufgeschoben. Es wollte einfach nicht klappen. Doch leider brauche ich umbedingt eine KI, weil mein bcc beitrag sonst sinnlos ist - aus man hat einen Bruder oder Kollegen, der mal grade ne runde zocken möchte *g* Schweren herzen gebe ich dann also doch ein paar informationen über mein Projekt bekannt - Es ist ein Snake Clon. Sehr eindrucksvoll, ich weiß ![]() Und hier liegt das problem - ich versuche mit winkeln zu arbeiten, doch anscheinend weiß icht NICHTS mehr aus meiner Schulzeit oO Nach ein wenig recherche, bin ich auf eine kleine erklärung zum Bogenmaß gekommen. Mir wurde gesagt, das ATan2 den winkel im bogenmaß rausgibt ![]() Wenn ich versuche, meine Rückgabe durch ATan2 in ein Winkelmaß umzurechnen, erhalte ich humbug. Werte von -7000 irgendwas. Nunja, ich denke ich habe hier ganz massiven förderbedarf. Und leider kann man nicht gegen einen Trottel von KI spielen, der stumpf grade aus läuft oder sich um die eigene Achse dreht. An sich ist mein vorhaben simpel: Gucken, liegt das ziel links oder rechts von meiner Blickrichtung? Rechts, okay, ab in die richtung drehen! Als hilfestellung habe ich 2 Zielkoordinaten, 2 Eigene koordinaten und einen Winkel (blickrichtung), anhand dessen ich die schlange auch verschiebe (Self.posx:+Cos(Winkel) , Self.posy:+Sin(Winkel) ) Mag mich hier nochmal jemand an die hand nehmen? :3 Gruß, Phillipk |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
also, du bist doch schon ganz nah dran...
hast du dir meinen demo-code von vor 3 tagen angeschaut? Da siehst du, dass der ATAN2 in BMAX nicht mit Bogenmass (wie in anderen Programmiersprachen) sondern glücklicherweise gleich mit Winkelangaben in Grad arbeitet. Du hast mit drei Winkeln zu kämpfen. Ich nenne sie hier einmal: WorldWinkel = wo steht der Gesuchte, wenn man man vom Himmel aus auf die Situation schaut SichtRichtung = wohin blickt der Verfolger, wenn er gerade aus schaut ZielWinkel = in welche Richtung muss der Verfolger drehen, wenn er zum Gesuchten sehen will Erst mal "World" Nun ist es ganz leicht den "World"-Winkel zwischen zwei Punkten zu berechnen. Dabei spielt es eigentlich noch keine Rolle mit welchem Winkel gerade der "Verfolger" unterwegs ist. Aus der "World"-Sicht befindet der "Gesuchte" irgendwo zwischen ... 0°-90° = links unterhalb des Verfolgers 90°-180° = links oberhalb des Verfolgers 180°-270° = rechts oberhalb des Verfolgers 270°-359° = rechts unterhalb des Verfolgers um jetzt das Ganze aus der Sicht des Verfolgers zu projezieren, musst Du eigentlich nur die Sicht-Richtung des Verfolgers abziehen. Beispiel A Der simple Fall Situation: Verfolger sieht in Richtung rechts oben, sagen wir SichtRichtung=240°, der gesuchte befindet sich links oberhalb des Verfolgers, sagen wir WorldWinkel=150°. ZielWinkel = 150°-240° = - 90° negatives Ergebnis bedeutet "links vom Verfolger" Bei dem ZielWinkel kann es eigentlich nur Werte zwischen -180° (ganz arg links hinter mir) und +180° (ganz arg rechts hinter mir) geben. Werte, die diesen Bereich verlassen, deuten auf ein überschreiten der 0°-Schwelle hin. Nach 359° kommt ja leider 0° und 10° und nicht 360°, 370°, ... deshalb nun... Beispiel B irgendwas stimmt nicht Situation: Verfolger sieht wieder in Richtung rechts oben, sagen wir SichtRichtung=240°, der gesuchte befindet sich links untenerhalb des Verfolgers, sagen wir WorldWinkel=30°. ZielWinkel 30°- 240° = -210° ABS(Wert) über 180 bedeutet 0°-Schwelle wurde überschritten. Hier zählt man nun 360° zu dem Ergebnis: ZielWinkel = -210° + 360° = +150° positives Ergebnis bedeutet "rechts vom Verfolger" Beispiel C anders herum Situation: Verfolger sieht in Richtung links unten, sagen wir SichtRichtung=10°, der gesuchte befindet sich rechts unterhalb des Verfolgers, sagen wir WorldWinkel=330°. ZielWinkel = 330°- 10° = +320° ABS(Wert) über 180 bedeutet 0°-Schwelle wurde überschritten. Hier zieht man nun 360° vom Ergebnis ab: ZielWinkel = 330° - 360° = -30° negatives Ergebnis bedeutet "links vom Verfolger" Zusammenfassung Code: [AUSKLAPPEN] WorldWinkel = Atan2 ( GesuchterX - VerfolgerX , GesuchterY - VerfolgerY )
WorldWinkel = (WorldWinkel +360° ) mod 360° ZielWinkel = WorldWinkel - SichtRichtung If ZielRichtung < - 180° ZielRichtung = ZielRichtung + 360° Endif If ZielRichtung > + 180° ZielRichtung = ZielRichtung - 360° Endif |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Midimaster hat Folgendes geschrieben: also, du bist doch schon ganz nah dran...
hast du dir meinen demo-code von vor 3 tagen angeschaut? Da siehst du, dass der ATAN2 in BMAX nicht mit Bogenmass (wie in anderen Programmiersprachen) sondern glücklicherweise gleich mit Winkelangaben in Grad arbeitet. Jaa die habe ich mehrmals Konsultiert *g* Aber irgendwie will mir das nicht in den Schädel rein. Vielleicht habe ich mich zulange damit rumgeärgert und nun sehe ich den Wald vor lauter Bäumen nicht ![]() Midimaster hat Folgendes geschrieben: Du hast mit drei Winkeln zu kämpfen. Ich nenne sie hier einmal: WorldWinkel = wo steht der Gesuchte, wenn man man vom Himmel aus auf die Situation schaut SichtRichtung = wohin blickt der Verfolger, wenn er gerade aus schaut ZielWinkel = in welche Richtung muss der Verfolger drehen, wenn er zum Gesuchten sehen will In Sichtrichtung bewegt sich meine KI (so wie auch jedes andere objekt, in ihrere individuelle sichtrichtung) Allerdings ist SichtRichtung nun gleichzeitig ein WorldWinkel, oder? Zumindest habe ich ihn dazu gemcht ![]() Zielwinkel ist das, was mir ATan2() also ausspuckt.. Midimaster hat Folgendes geschrieben: Zusammenfassung Code: [AUSKLAPPEN] WorldWinkel = Atan2 ( GesuchterX - VerfolgerX , GesuchterY - VerfolgerY )
WorldWinkel = (WorldWinkel +360° ) mod 360° ZielWinkel = WorldWinkel - SichtRichtung If ZielRichtung < - 180° ZielRichtung = ZielRichtung + 360° Endif If ZielRichtung > + 180° ZielRichtung = ZielRichtung - 360° Endif Und wieder was gelernt :3 Ich wusste, da kann was nicht passen, wenn ich -7000° rauskriege ![]() Ich werde einmal grade dein Codebeispiel 1zu1 auf mein jetziges 'System' portieren. Danke schonmal, für deine weitere hilfe ![]() Ps: Ich habe mir die beiden beispielcodes angeschaut und auch teile davon übertragen. Überall schien es logikfehler zu geben. Der vielversprechendste versuch hat mich allerdings auf 45° genau das ziel ansteuern lassen :< (ich muss mit erschrecken feststellen, wie schnell ich doch Sachen vergesse.. Noch vor nem halben jahr habe ich mir eine 3d Physik engine (mit einiger hilfe hier aus dem forum *g*) geschrieben und dort fast in jeder Zeile mit Winkeln und Vektoren hantiert. Und jetzt kriege ich nichtmal eine Simple 2d- winkeldifferenz zu stande ![]() |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
Hier irrst Du:
Zitat: ...Allerdings ist SichtRichtung nun gleichzeitig ein WorldWinkel, oder?...
die SichtRichtung kann niemals gleich dem WorldWinkel sein. In meiner Demo siehst Du es. Hier siehtst Du eine Welt in der ein dritter Betrachter ein festes Koordinatensystem hat. Beide Akteure sind zu sehen: Der Verfolger steht fest in der Mitte und der Gesuchte umkreist ihn. Der World-Winkel (, der immer vom Verfolger auf den Gesuchten zeigt, ) läuft wie auf einer Uhr: 0° = 6:00 Uhr 90° = 9:00 Uhr 180° = 12:00 Uhr 270° = 15:00 Uhr Zitat: Zielwinkel ist das, was mir ATan2() also ausspuckt.
leider auch falsch gedacht! Der Atan2() spuckt erst den WorldWinkel aus. Schließlich wird er ja aus Koordinaten der Welt heraus berechnet. |
||
- Zuletzt bearbeitet von Midimaster am Di, Aug 02, 2011 9:28, insgesamt einmal bearbeitet
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Wuha, es klappt o.o
Ich habe grade versucht, die KI auf den Punkt der maus auszurichten. Es funktioniert - tatsächlich *-* Ich bin begeistert! Das heißt, nun kann ich enldich die ki einbauen ![]() ![]() Ich danke dir Midimaster, für diese doch recht simple aber funktionierende lösung ![]() Weiß der teufel, warum ich das nicht hinbekommen hab :< |
||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Midimaster hat Folgendes geschrieben: Hier irrst Du:
Zitat: ...Allerdings ist SichtRichtung nun gleichzeitig ein WorldWinkel, oder?...
die SichtRichtung kann niemals gleich dem WorldWinkel sein. In meiner Demo siehst Du es. Hier siehtst Du eine Welt in der ein dritter Betrachter ein festes Koordinatensystem hat. Beide Akteure sind zu sehen: Der Verfolger steht fest in der Mitte und der Gesuchte umkreist ihn. Der World-Winkel (, der immer vom Verfolger auf den Gesuchten zeigt, ) läuft wie auf einer Uhr: 0° = 6:00 Uhr 90° = 9:00 Uhr 180° = 12:00 Uhr 270° = 15:00 Uhr Zitat: Zielwinkel ist das, was mir ATan2() also ausspuckt.
leider auch falsch gedacht! Der Atan2() spuckt erst den WorldWinkel aus. Schließlich wird er ja aus Koordinaten der Welt heraus berechnet. Argl. Ich brauch endlich wieder Papier und stif am PC Tisch. Vielleicht komme ich dann nicht ganz so dämlich rüber, wenn ich klammheimlich erstmal alles durchskizzieren kann :3 Mit paint und co ists einfach nicht das wahre ![]() |
||
![]() |
Midimaster |
![]() Antworten mit Zitat ![]() |
---|---|---|
chat??? | ||
PhillipK |
![]() Antworten mit Zitat ![]() |
|
---|---|---|
Bin ein wenig in Zeitdruck, die Fahrstunde beginnt gleich *g*
Allerdings läuft es schon einigermaßen sauber. Hier und da noch ne begrenzung, bis ich wieder vor die wand fahre.. Das wird schon irgendwie :3 |
||
Übersicht


Powered by phpBB © 2001 - 2006, phpBB Group