Best Practice Punkt im dreidimensionalen Raum Bestimmen

Diskutiere Punkt im dreidimensionalen Raum Bestimmen im Allgemeine Java-Themen Bereich.
S

Skyriiy

Hallo liebe Code Gemeinde,
beim Coden bin ich auf ein kleines Problem gestoßen und finde gerade keine funktionierende Lösung. Zu meinem Problem:

Ich habe 2 Punkte (P1 und P2) welche sich im dreidimensionalen Raum befinden. P1 ist ein bewegliches Objekt welches sich frei im Raum bewegen kann. P2 ist ein fester Punkt.

Nun möchte ich einen weiteren Punkt (P3) mit etwas Abstand vom P2 bestimmen um ein rechtwinkliges Dreieck zwischen den Punkten zeichnen zu können. Die Hypotenuse liegt dabei gegenüber von P2.

Wie kann ich das in Java am besten umsetzen?

Vielen Dank schonmal im voraus.

Grüße Sky
 
Zuletzt bearbeitet:
S

Skyriiy

Ich weiß nicht wie ich die Methode zum errechnen von P3 machen muss.
 
H

httpdigest

Das Problem ist in 3D nicht wohldefiniert. Es gibt unendlich viele Positionen für P3, so dass sich ein rechtwinkliges Dreieck zwischen P1, P2 und P3 ergibt.
Siehe Zeichnung:
P3 kann bei gegebener Konfiguration von P1 und P2 auf jedem Punkt des gepunkteten Kreises sein und P1P2P3 wäre immer noch ein rechtwinkliges Dreieck (in 3D!).
 
L

LimDul

Ist das überhaupt eindeutig? Aus dem Bauch heraus würde ich vermuten, dass P3 mindestens auf einer Kreisbahn liegen kann Ansonsten ist das eigentlich kein Java-Problem, sondern ein mathmatisches. Mal das mal auf und versuche das mathematische Problem zu lösen.
 
H

httpdigest

Wenn du nur irgendeinen Punkt P3 haben möchtest, so dass P3 `d` Längeneinheiten von P2 entfernt ist und P1P2P3 ein rechtwinkliges Dreieck bilden, dann:
Java:
public class PunktFuerRechtwinkligesDreieck {
  public static class Vector3f {
    float x, y, z;
    public Vector3f(float x, float y, float z) {
      this.x = x;
      this.y = y;
      this.z = z;
    }
    public String toString() {
      return "(" + x + ", " + y + ", " + z + ")";
    }
  }
  public static Vector3f findeP3(Vector3f p1, Vector3f p2, float d) {
    float ax = p2.x - p1.x, ay = p2.y - p1.y, az = p2.z - p1.z;
    float s = d / (float) Math.sqrt(ax * ax + ay * ay + az * az);
    if (ax == 0)
      return new Vector3f(p2.x + d, p2.y, p2.z);
    else if (ay == 0)
      return new Vector3f(p2.x, p2.y + d, p2.z);
    else
      return new Vector3f(p2.x - ay * s, p2.y + ax * s, p2.z + az * s);
  }
  // Test
  public static void main(String[] args) {
    System.out.println(findeP3(new Vector3f(0, 0, 0), new Vector3f(1, 1, 0), 1));
  }
}
 
Zuletzt bearbeitet:
H

httpdigest

Naja, die zusätzliche Information, dass "P1 sich frei im Raum bewegt" ist völlig uninteressant für die Beantwortung der Frage. Natürlich ändert sich die Position von P3, wenn sich die Position von P1 ändert. Aber in jedem Fall musst du für eine gegebene Position von P1 und P2 eine neue Position für P3 ausrechnen. Und hier liegen nunmal gültige Positionen auf einem Kreis in 3D.
 
A

abc66

Naja, die zusätzliche Information, dass "P1 sich frei im Raum bewegt" ist völlig uninteressant für die Beantwortung der Frage
Nein ist es nicht. Weil die Frage damit blödsinnig ist. Und dein Code beruht auch auf einer gegenteiligen Annahme der Fragestellung.

Wenn ein Punkt beweglich ist, ist eine auf einem festen Punkt beruhende Lösung schlicht falsch.
 
H

httpdigest

Dann verrate mir mal, wie er/sie dann:
Nun möchte ich einen weiteren Punkt (P3) mit etwas Abstand vom P2 bestimmen um ein rechtwinkliges Dreieck zwischen den Punkten zeichnen [zu] können.
Ein Dreieck zu zeichnen, für das sich eine Ecke ständig bewegt, ist relativ schwierig.
 
H

httpdigest

Wenn P3 nun den selben Y-Wert hat wie P2. Müsste man doch 2 Positionen für P3 bestimmen können oder nicht?
Dann gibt es immer noch unendlich viele Positionen für P3 mit demselben Y-Wert wie P2. In diesem Fall liegt dann P1 ja direkt oberhalb (+Y) oder unterhalb (-Y) von P2 und P3 kann um die Y-Achse rotieren.

EDIT: Mit Illustration:
 
Zuletzt bearbeitet:
S

Skyriiy

Hmm okay. Ich hab das Problem mal umgeformt. Vielleicht kommen wir da einer Lösung näher die sich nicht in der Unendlichkeit verliert ^^"

P1 ist immer noch ein bewegbarer Punkt.
P2 ist immer noch ein fest stehender Punkt.
P3 und P4 haben einen Abstand von d2 zu P2 und befinden sich auf der selben höhe wie P2.
P5 und P6 haben den selben X und Z Wert wie P4 bzw. P3 und sind lediglich um d1 auf der Y-Achse verschoben.

Die Werte von d1 und d2 stehen fest und ändern sich nie.
Die Fläche die sich aus P3, P4, P5 und P6 bildet zeigt also in Richtung P1.


Wie komme ich an die Punkte P3 und P4?
 
H

httpdigest

Also: Wir reden hier nicht von drei Dimensionen, sondern von zwei?
 
S

Skyriiy

Wir reden hier nicht von drei Dimensionen, sondern von zwei?
In dem 2. Fall sind 2 Dimensionen eigentlich genug. Das verschieben von P5 und P6 ist kaum eine Kunst. Das sollte ich hinbekommen :)

Ich weiß nur nicht wie ich es hin bekomme, dass sich P1 frei bewegen kann und P3 und P4 einfach nachziehen und sich Ihre Position in der "Umlaufbahn" von P2 suchen.
 
N

Neumi5694

Deine Abstände ignorier ich jetzt gerade mal, Strecken kann man hinterher immer noch. Wichtig sind im ersten Moment nur die Winkel.
Unterm Strick geht's aber drum, die Achsen eines orthogonalen Koordinatensystems zu berechnen, P1->P2 (oder umgekehrt) gibt dabei die Z-Achse vor.

Damit gibt es immer noch unendlich viele Lösungen. Im Bild von httpdigest siehst du recht gut, wieso.
P3 kann auf der Kreisbahn rotiert werden. P4 muss dann nur noch auf der selben Ebene orthogonal dazu liegen.

Hier ein Ansatz.
Jede Drehung im Raum lässt sich (es gibt auch noch andere Möglichkeiten, das hier ist eine in der Technik gängige, da leicht verständlich) durch 3 einfache Drehungen erreichen.
1. Drehen um die Z-Achse
2. Drehen/Kippen um die (lokale) X-Achse
//an diesem Punkte hast du die im BIld sichtbare Kreis-Ebene, was noch fehlt, ist die Ausrichtung für P3
3. Drehen um die (lokale) Z-Achse

Hier ein paar Fälle (nicht vollständig, es gibt noch weitere), wie du zu den Drehungen kommst.
Zeigt deine Z-Achse senkrecht nach oben, so gibt es lediglich eine (mögliche) Drehung in (1) und/oder (3)
Zeigt deine Z-Achse nach senkrecht nach unten, so war die Drehung in (2) genau 180°, zusätzlich wird noch in (1) und/oder (3) gedreht.
Liegt deine Z-Achse horizontal, so finde den X/Y-Winkel deiner Achse raus, addiere 90°, dann hast du (1), sofern die y-Achse nach oben zeigen soll. Soll sie nach unten zeigen, dann sind 90° abzuziehen. Soll die Y-Achse nach unten zeigen, dann wähle den Absolutwert von (3) > 90.
Wenn du diese 3 Drehungen hast, kannst du ein Standard-Koordinatensystem per Matritzenmultiplikation drehen, um die Achsen zu kriegen.

Für dein Problem musst du die Winkel für 1 und 2 rauskriegen. Die Ausrichtung der Achsen auf der Kreislinie scheint die nicht wichtig zu sein.

Achtung: Ich hab das mal aus dem Stehgreif geschrieben, es kann schon sein, dass ich hie und da falsch liege. Vielleicht gibt's auch noch eine effizientere Methode. So hab ich's aber (vor Jahren) umgesetzt. Für den Fall, dass es als Quellinfos ausschließlich 2 Punkte gibt, nehme ich (3) immer als 0 an. So bleibt die X-Achse immer horizontal, Y zeigt - sofern der Absolutwert von (2) < 90 immer nach oben.
 
H

httpdigest

Das Problem kann man auch ganz elegant in 2D mit linearer Algebra lösen. Hier sind Winkel und transzendente Funktionen nicht unbedingt nötig. Wenn wir uns also auf 2D beschränken, dann:
Java:
// given two arbitrary 2D positions P1 and P2:
float p1x = 1, p1y = 3;
float p2x = 4, p2y = 3;
// compute direction vector `a` from p1 to p2 (= p2 - p1):
float ax = p2x - p1x, ay = p2y - p1y;
// normalize this direction vector into `n` (= a/|a|):
float inv = 1.0f / (float) Math.sqrt(ax*ax + ay*ay);
float nx = ax * inv, ny = ay * inv;
// compute vector `d` perpendicular to `n` (dx, dy) = (ny, -nx) ; essentially a clockwise rotation around the z-axis by 90°:
float dx = ny, dy = -nx;
// given some distance `d2`:
float d2 = 0.4f;
// compute P3 (= p2 + d * d2):
float p3x = p2x + dx * d2, p3y = p2y + dy * d2;
// compute P4 (= p2 - d * d2):
float p4x = p2x - dx * d2, p4y = p2y - dy * d2;
// given some distance `d1`:
float d1 = 0.2f;
// compute P5 (= p4 + n * d1):
float p5x = p4x + nx * d1, p5y = p4y + ny * d1;
// compute P6 (= p3 + n * d1):
float p6x = p3x + nx * d1, p6y = p3y + ny * d1;
 
Thema: 

Punkt im dreidimensionalen Raum Bestimmen

Passende Stellenanzeigen aus deiner Region:
Anzeige

Neue Themen

Anzeige

Anzeige
Oben