Steering Hide, Interpose

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
hell
User
Beiträge: 40
Registriert: Montag 1. Oktober 2018, 18:01

hi _blackjack_
exakt, und deshalb ist die collision_avoidance auch ziemlich armselig und müsste überarbeitet werden z.B mit einer Boundingbox um die
Vehikel mit einer dynamischen Länge, abhängig von der Geschwindigkeit , wie bei Buckland. Was mir aber sofort neue Probleme einbringt ( Thema lokales Koordinatensystem vs globales Koordinatensystem: ???????). Einfacher wären Fühler zur Seite. Oder die Steuerung des Vehikels zusätzlich mit seitlichen Vektoren, usw.
Was mich immer noch beschäftigt ist das zweite Problem:
-welche Relevanz hat das Problem und wie wirkt es sich auf die Steuerung der Vehikel aus.
-wenn apply_force(steer * len(walls)) läuft, warum nicht stattdessen apply_force(steer / len(walls)) ????
Ehrlich gesagt, ich habe keinen Schimmer.
hell
hell
User
Beiträge: 40
Registriert: Montag 1. Oktober 2018, 18:01

hallo _blackjack_,
vielleicht kannst du so nett sein und noch *einmal* antworten.
Du hast recht, du hast so ziemlich alles wichtige zerschlagen und da ich deinen Code in hide und collision_avoidance
(noch) nicht verstehe, so blieb mir keine andere Wahl diese wieder zu ändern unter Beibehaltung deiner Codestruktur.
1. Funktion get_hiding_position -> Compiler meckert: Attributerror oder so, d.h. er kann z.B.obstacle.location nicht finden
(ist eigentlich auch klar ): also habe ich die Funktion wieder so geändert -> die Argumente nur Platzhalter

Code: Alles auswählen

def get_hiding_position(obstacle, radius, agent):
    # 
    # Calculate the heading toward the obstacle from the agent.
    # 
    agent_to_obstacle = (obstacle - agent).normalize()
    # 
    # Scale it to size and add to the obstacle's position to get
    # the hiding spot.
    # 
    agent_to_obstacle.scale_to_length(radius + 20.0)
    return agent_to_obstacle + agent
und dann in hide die Funktion so aufgerufen:

Code: Alles auswählen

hiding_spot = get_hiding_position(wall.location, 
                                              wall.radius,
                                              hunter.location)
Allerdings funktioniert hiding-Verhalten nicht so richtig. Ich vermute es liegt an ff. Codezeile:

Code: Alles auswählen

dist = hiding_spot.distance_to(hunter.location) 
Hier rufst du, wenn ich das recht sehe , die Methode distance_to der Wallklasse auf. Das ist für mich (und für den Compiler vielleicht auch ) recht verwirrend, da sie den gleichen Namen hat wie die der Vektorklasse Vector2.

2.Diese Methode hat allerdings wiederum Auswirkungen auf die Funktion calculate_non_overlapping_circles. Hier rufst du ganz offensichtlich mit ff Code:

Code: Alles auswählen

if not any(map(wall.overlaps, walls)):
ebenfalls die Wall-Methode distance_to auf. Und ab hier habe ich dann aufgegeben.

3. Die Methode collision_avoidance habe ich ebenfalls wieder rückgängig gemacht, da auch hier der Compiler gemeckert hat und ( wie gesagt, da ich *noch* deinen Code verstehe ) die ursprünglich Form hergestellt. Was dann funktionierte.

Um deine Code zu testen, benötigst du die Bilder auf Eli Benderskys Webseite hier:Bild

Im übrigen möchte ich die noch einmal ganz herzlich danken für deine Geduld mit mir, mit dem bereinigte Code von dir sind so einige unsinnige Dinge aus der Welt.
Eine Frage habe ich noch: ich verwende den Editor geany, hauptsächlich, weil ich die Programm von da heraus problemlos starten kann, allerdings hat geany ziemlich Probleme mit der Einrückung, glaube ich, sie sind nämlich von Datei zu Datei optisch ganz verschieden breit. Ich habe mich schon einmal an atom versucht, jedoch will der die Programme nicht starten und findet auch python 3 nicht.
Was kannst du mir empfehlen?
gruss hell
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Die get_hiding_position Funktion ist Unfug. Sie tut nicht, was ihr eigener Kommentar beschreibt. Das Folgeverhalten kann dann wohl kaum erfolgreich ausfallen.

Der normalisierte Vektor geht in die falsche Richtung. Er zeigt WEG vom Agenten. Er muss aber ZU dem Agenten zeigen, damit man ihn korrekt skaliert auf die Position des HINDRENISSES addieren kann. Denn man will sich ja in der Nähe der Wand verstecken. Stattdessen addierst du ihn auf die Position des Agenten, der sich damit in der konsequenz ein bisschen auf das Hindernis zu bewegt, aber nicht versteckt.

Dieser Post ist frei von fortgeschrittenen Python-Konzepten & enthält nur grundlegende Vektormathematik.
hell
User
Beiträge: 40
Registriert: Montag 1. Oktober 2018, 18:01

danke _deets_ ,
habe Fehler gefunden. Die Funktion muss so lauten:

Code: Alles auswählen

def get_hiding_position(obstacle, radius, target): 
    # Calculate the heading toward the obstacle from the agent.
    # 
    agent_to_obstacle = (obstacle - target).normalize()
    # 
    # Scale it to size and add to the obstacle's position to get
    # the hiding spot.
    # 
    agent_to_obstacle.scale_to_length(radius + 20.0)
    return agent_to_obstacle + obstacle
wobei target für den hunter steht.
gruss hell
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn man sich VOR dem target verstecken soll, ja. Dann klingt das sinnvoll.
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hell: Das verschiedene Datentypen Methoden mit den gleichen Namen haben verwirrt vielleicht Dich, aber ganz sicher nicht den Compiler/Python, denn das ist normal. Das man das machen kann ist einer der Vorteile von objektorientierter Programmierung. Stichwort: Polymorphie.

Und es ist auch nicht so ungewöhnlich, dass man Klassen hat und darauf Methoden definiert deren AUfruf mehr oder weniger 1:1 an einen Bestandteil des Objekts durchgereicht wird. Es macht bei `Wall`- und `Vehicle`-Objekten Sinn den Abstand zwischen beiden zu berechnen, und dafür macht der Methodenname `distance_to()` Sinn. Genau so wie es Sinn macht den Abstand zwischen zwei Ortsvektoren vom Typ `Vector2` zu berechnen, und da ist ebenfalls `distance_to()` ein passender Name. Und wenn `Wall`/`Vehicle` ihre Position mit einem `Vector2` beschreiben, wird die `distance_to()` von `Wall`/`Vehicle` natürlich die `Vector2.distance_to()` zur Berechnung heranziehen.

Was man da eigentlich noch machen müsste, wäre die Radii von den beiden beteiligten Objekten abziehen um den Abstand genauer zu berechnen. Und spätestens an der Stelle macht es auch wirklich Sinn das in einer Methode auf `Wall`/`Vehicle` zu machen und nicht immer von Aussen auf die `location` zuzugreifen wie Du das gemacht hast, denn das mit den Radii müsste man dann überall hinschreiben wo man den Abstand zwischen den Objekten berechnen will.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Benutzeravatar
__blackjack__
User
Beiträge: 13100
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@hell: Noch ein Nachtrag: Vielleicht solltest Du besser von Deinem Code ausgehen statt bei meinem ”Rückbau” zu betreiben, da ich ja wie gesagt nicht weiss ob ich nicht noch irgendwo etwas kaputt gemacht habe, beim umschreiben ohne Testläufe.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
hell
User
Beiträge: 40
Registriert: Montag 1. Oktober 2018, 18:01

hallo _blackjack_,
danke für deine Antwort.
Meine nächsten 'Projekte' werden sein, zunächst die Programm zu den einzelnen Steering Behaviors von allem redundanten Code zu 'befreien'. Und OOP lernen. Vielleicht komme ich dann irgendwann dahin alle Themen, die du empfohlen hast, auch umzusetzen.
grüsse hell
Antworten