0 Daumen
632 Aufrufe

Ich habe ein Problem, welches ich nicht mit normalen Methoden lösen kann. Ich arbeite gerade an einem Unity Projekt mit dem ich ein Festival/Konzert Simulieren will. dabei will ich die neue DOTS Technologie von Unity verwenden, mit der es mir möglich ist viele hundert tausende kapseln zu generieren und sich bewegen zu lassen etc.

Mein Gelände war in den letzten Wochen dabei immer rechteckig. Ich hatte also 2 Punkte P1 und P2 unten für die x Achse mit denen ich dann zufällig einen x Wert generiert habe: Random.Range(P1.x, P2.x) und einen Punkt im hinteren Bereich des Geländes P3 mit dem ich einen zufälligen Wert für die Z Achse berechnen kann: Random.Range(P2.z, P3.z).

Ich wollte jetzt eine Funktion einbauen, mit dem der Nutzer das Konzertgelände vergrößern kann, also wenn er 1 drückt, dann rotieren die beiden Seitlichen Absperrungen um 60°, sodass die Konzertfläche größer wird. Später will ich auch weiter in die weite gehen, also noch ein paar Seitliche Absperrungen hinten dran hängen.

Hier mal ein Bild, wie die rotierte Seitenwand aussieht:

Bild 2.PNG

Diese schwarze Linie stellt einen Zaun dar. Die weißen Punkte bilden Punkte ab, welche ich momentan im Programmcode verwende.

Bild 1.jpg

Die gelben stellen zeigen, wo genau ich im Moment meine Punkte verteilt habe. Es werden x Koordinaten im Bereich unten zwischen den beiden unteren gelben Punkten und z Koordinaten zwischen einem gelben Punkt unten und einem gelben Punkt hinten generiert.


Mein Problem ist jetzt, dass ich halt keine agents im außenbereich haben will, ich habe diesen auch rot markiert. Ein weiteres Problem ist, dass ich keinen großen Zugriff auf verschiedenen Bibliotheken habe mit denen man vielleicht sowas automatisieren könnte. Ich habe nur die Möglichkeit das ganze mit Abfragen zu umgehen. Also

if(randomPosition ist außerhalb von Trapez) => generiere für diesen agent eine neue randomPosition.

Ich habe nur Zugriff auf die verschiedenen gelben Punkte und die generierte Position in Vector3 Form.

Ich komme bei diesem Problem im Moment einfach nicht weiter, vielleicht hat ja jemand eine Idee wie ich das hin bekommen könnte.

Konnte das Problem mit einem Algorithmus lösen, welcher checkt, ob ein Punkt in einem Dreieck ist oder nicht. Ich generiere also einen Punkt wie in den oberen Bildern. Wenn der Punkt nun in einem der beiden Dreiecke ist, dann generiere ich eine neue zufällige Position und checke erneut.
Wenn die zufällige Position nicht in einem der beiden Dreiecke ist, dann behalte ich die Position und setze einen agent an dieser Stelle.

Bild 3

Avatar von

1 Antwort

0 Daumen

Antwort mit KI erzeugt

Lösung des Problems mit einem Algorithmus

Um das Problem zu lösen, bei dem Agenten nicht in bestimmten Außenbereichen eines durch eine Nutzereingabe (in diesem Fall das Drücken der Taste "1") modifizierten Konzertgeländes generiert werden sollen, können wir einen effektiven Algorithmus einsetzen. Dies wird dadurch erreicht, dass überprüft wird, ob eine generierte Position innerhalb der zulässigen Konzertfläche liegt, die jetzt eine trapezförmige Form angenommen hat, anstatt vollständig rechteckig zu sein, wie es zuvor war.

Die trapezförmige Fläche kann als Kombination aus zwei Dreiecken betrachtet werden. Der Schlüssel zur Lösung dieses Problems liegt darin, einen Algorithmus zu nutzen, der effizient bestimmen kann, ob ein generierter Punkt innerhalb dieser beiden Dreiecke liegt.

Schritte zur Implementierung:

1. Identifiziere die Eckpunkte des Trapezes: Diese wurden bereits als gelbe Punkte im ursprünglichen Setup festgelegt. Wir müssen sicherstellen, dass wir diese Punkte kennen und ihre Koordinaten korrekt identifizieren können.

2. Dreiecksüberprüfung für die generierte Position: Für jede generierte Position überprüfen wir, ob der Punkt innerhalb eines der beiden Dreiecke liegt, die das Trapez bilden. Dies kann durch einen Punkt-in-Dreieck-Test erreicht werden.

3. Punkt-in-Dreieck-Test: Um zu überprüfen, ob ein Punkt \(P\) innerhalb eines Dreiecks mit den Eckpunkten \(A\), \(B\), und \(C\) liegt, kann die Baryzentrische Koordinatenmethode oder eine andere Methode verwendet werden. Für unseren Zweck könnte ein einfacher Ansatz genügen, der überprüft, ob die Summe der Flächen der Dreiecke \(APB\), \(APC\), und \(BPC\) gleich der Fläche des ursprünglichen Dreiecks \(ABC\) ist. Wenn ja, dann liegt \(P\) innerhalb des Dreiecks.

4. Generierung einer neuen Position: Falls der Punkt außerhalb der zulässigen Bereiche liegt, muss eine neue Position generiert und der Prozess wiederholt werden, bis eine gültige Position gefunden wird.

Beispiel-Code (Pseudo-Code/Unity C# Code-Snippet):

csharp
bool IsPointInTriangle(Vector3 P, Vector3 A, Vector3 B, Vector3 C) {
    // Berechne die Flächen und prüfe die Bedingungen (einfacher Algorithmus oder Baryzentrische Methode)
    // Für Pseudocode Zwecke überspringen wir die spezifische Implementierung
    return conditionThatValidatesPointInTriangle;
}

Vector3 GenerateValidPosition(Vector3[] trapezoidPoints) {
    Vector3 randomPosition;
    do {
        randomPosition = new Vector3(Random.Range(...), 0, Random.Range(...));
    } while (!IsPointInTriangle(randomPosition, trapezoidPoints[0], trapezoidPoints[1], trapezoidPoints[2]) &&
             !IsPointInTriangle(randomPosition, trapezoidPoints[1], trapezoidPoints[2], trapezoidPoints[3]));
    return randomPosition;
}

// Nutzen Sie die `GenerateValidPosition` Methode mit den entsprechenden Eckpunkten Ihres Trapezes
Vector3[] trapezoidPoints = { /* Setzen Sie die 4 Eckpunkte hier ein */ };
Vector3 validPosition = GenerateValidPosition(trapezoidPoints);


Der Schlüssel liegt darin, die GenerateValidPosition-Funktion so anzupassen, dass sie Ihre spezifischen Eckpunkte verwendet und die Logik des Punkt-in-Dreieck-Tests korrekt implementiert. Dieser Beispielcode ist eine Grundlage und sollte sowohl an die genaue Definition der Trapezfläche als auch an die spezifischen Anforderungen Ihrer Simulation angepasst werden.
Avatar von 2,9 k

Ein anderes Problem?

Stell deine Frage

Ähnliche Fragen

0 Daumen
1 Antwort
0 Daumen
1 Antwort
0 Daumen
1 Antwort
Gefragt 19 Mär 2018 von Gast

Willkommen bei der Stacklounge! Stell deine Frage einfach und kostenlos

x
Made by a lovely community