Ray - Position wenn Y = 0

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 9 Antworten in diesem Thema. Der letzte Beitrag () ist von φConst.

    Ray - Position wenn Y = 0

    Hallo,
    ich versuche gerade die Komponenten X, und Z zu berechnen, wenn Y = 0 ist.

    Ein Ray behandelte ich wie eine Gerade.

    Im linearen System berechne ich die X -Komponente für ein Y = beliebig wie folgt;

    x_bei_y_beliebig = -(m * (y_position - y_beliebig)) + x_position

    Exemplarisch : x = 15 und y = 30 und m = -1
    Wann ist y = 15

    x = -(-1*(30-15))+15=30

    Übertragen auf ein Ray:

    C#-Quellcode

    1. public Vector3 GetXZForY(Ray ray, float y)
    2. {
    3. float m_x = ray.Direction.Y / ray.Direction.X;
    4. float m_z = ray.Direction.Z / ray.Direction.X;
    5. return new Vector3(-(m_x * (ray.Position.Y - y)) + ray.Position.X, 0, -(m_z * (ray.Position.Y - y)) + ray.Position.Z);
    6. }


    Anfangs war mein Versuch

    C#-Quellcode

    1. public Vector3 GetXZForY(Ray ray, float y)
    2. {
    3. return new Vector3(-(ray.Direction.X * (ray.Position.Y - y)) + ray.Position.X, 0, -(ray.Direction.Z * (ray.Position.Y - y)) + ray.Position.Z);
    4. }


    Zur Berechnung des Rays bediene ich mich folgender Methode:

    C#-Quellcode

    1. public static Ray CalculateRay(Vector2 mouseLocation, Matrix view, Matrix projection, Viewport viewport)
    2. {
    3. Vector3 nearPoint = viewport.Unproject(new Vector3(mouseLocation.X,
    4. mouseLocation.Y, 0.0f),
    5. projection,
    6. view,
    7. Matrix.Identity);
    8. Vector3 farPoint = viewport.Unproject(new Vector3(mouseLocation.X,
    9. mouseLocation.Y, 1.0f),
    10. projection,
    11. view,
    12. Matrix.Identity);
    13. Vector3 direction = farPoint - nearPoint;
    14. float n = direction.X * direction.X + direction.Y * direction.Y + direction.Z * direction.Z;
    15. float n1 = 1f / (float)Math.Sqrt((double)n);
    16. direction.X *= n1;
    17. direction.Y *= n1;
    18. direction.Z *= n1;
    19. return new Ray(nearPoint, direction);
    20. }



    Meine Intention:
    Ich versuche ein Objekt mit der Maus zu führen.
    Dabei muss die Y-Komponente des Objektes immer 0 sein. (Y=0)

    Ray - BoundingBox -Intersection funktioniert hervorragend; egal aus welcher Perspektive ich schaue..

    Nur die Positionsbestimmung will nicht..

    Im Anhang finden sich die Screenshots wieder..
    Die gelben Pfeile markieren approximiert die Position des Cursors..(Windows fängt Cursor beim Screenshot nicht ein)


    Liebe Grüße...
    Bilder
    • Screenshot (234).png

      157,48 kB, 1.920×1.080, 195 mal angesehen
    • Screenshot (235).png

      158,4 kB, 1.920×1.080, 144 mal angesehen
    • Screenshot (236).png

      115,41 kB, 1.920×1.080, 148 mal angesehen
    Und Gott alleine weiß alles am allerbesten und besser.

    φConst schrieb:

    C#-Quellcode

    1. return new Vector3(-(m_x * (ray.Position.Y - y)) + ray.Position.X, 0, -(m_z * (ray.Position.Y - y)) + ray.Position.Z);
    Das sieht gar nicht gut aus.
    Fang an und schreib die 3 Komponenten immer untereinander in je eine neue Zeile.
    Dann machst Du Dir eine allgemeine Funktion: Ortsvektor Resultat = Ortsvektor Start + Faktor * Richtungsvektor, das für 3 Komponenten, wobei der Faktor für alle 3 Komponenten gleich ist:

    C#-Quellcode

    1. public static Vektor PunktAufGerade(Vektor start, Vektor richtung, double faktor)
    2. {
    3. double x = start.X + faktor * richtung.X;
    4. double y = start.Y + faktor * richtung.Y;
    5. double z = start.Z + faktor * richtung.Z;
    6. return new Vektor(x, y, z);
    7. }
    Und dann überlegst Du, was sich vereibfacht, wenn Deine Randbedingungen gelten sollen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo,
    anfangs hatte ich bedenken wegen des Richtungsvektors..

    Kann ich den Richtungsvektor als m , ähnlich bei m*x + b , betrachten?

    Wie sieht denn der Y-Achsen-Abschnitt im dreidimensionalen Raum aus?

    EDIT: Gibt's nicht!
    Ich denke mal, die Start-Position, ist jene Position, mit der ich den Ray instanziiert habe.. stimmt's?



    Ich meine.. wenn der Richtungsvektor gen Z-Achse zeigt, und exemplarisch X = 15 nach rechts verschoben vorliegt, berührt es die Y-Achse nie...

    Gruß.
    Und Gott alleine weiß alles am allerbesten und besser.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „φConst“ ()

    Jo, könnte man so sehen. Du hast im 3-dimensionalen Raum nur einen Aufhängepunkt/Stützvektor (entsprechender Ortsvektor) und dann gibst Du mit dem Richtungsvektor an, in welche Richtung die Gerade entsprechend verlaufen muss. (Zumindest in der Parameterform)
    Lambda ist dann nur noch ein entsprechender Faktor, um auf der Geraden sozusagen "langzulaufen".

    Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Hallo,

    C#-Quellcode

    1. public static Vector3 GetYEquals0(Ray ray)
    2. {
    3. // y = mx+b
    4. // 0 = mx+b
    5. // -b = mx
    6. // -b/m = x
    7. var lambda = -ray.Position.Y / ray.Direction.Y;
    8. var xCoord = ray.Direction.X * lambda + ray.Position.X;
    9. var yCoord = ray.Direction.Y * lambda + ray.Position.Y;
    10. var zCoord = ray.Direction.Z * lambda + ray.Position.Z;
    11. return new Vector3(xCoord, yCoord, zCoord);
    12. }


    Scheint zu funktionieren.. leider gibt's nur noch ein kleines Problem:

    C#-Quellcode

    1. var yCoord = ray.Direction.Y * lambda + ray.Position.Y;
    gibt nicht null, sondern 0.00000026054704
    aus.. obwohl
    exemplarisch lambda = 21.2132034 * 0.00000026054704 + 15 = 0 sein sollten. Ist wohl ein Kommafehler, gel?

    Edit: Funktioniert leider nicht.

    EDIT II:

    C#-Quellcode

    1. public static Vector3 GetYEquals0(Ray ray, float y)
    2. {
    3. // y = mx+b
    4. // 1 = mx+b
    5. // 1-b = mx
    6. // 1-b/m = x
    7. var lambda = (y - ray.Position.Y) / ray.Direction.Y;
    8. var xCoord = (double)(ray.Direction.X * lambda + ray.Position.X);
    9. var yCoord = (double)(ray.Direction.Y * lambda + ray.Position.Y);
    10. var zCoord = (double)(ray.Direction.Z * lambda + ray.Position.Z);
    11. return new Vector3((float)xCoord, (float)yCoord, (float)zCoord);
    12. }


    Funktioniert jetzt... Klammer bei

    C#-Quellcode

    1. (y - ray.Position.Y) / ray.Direction.Y;
    fehlte... nichtsdestotrotz habe ich das selbe Problem mit dem Objekt...
    Wenn ich die Perspektive wechsel, verschiebt sich das Objekt nur träge .

    EDIT : Krank!
    Hat funktioniert.. lag nur an der Klammer.. für alle, die sich des gleichen Problems widmen :

    C#-Quellcode

    1. public Vector3 GetXZAtY(Ray ray, float y)
    2. {
    3. // y = mx+b
    4. // 1 = mx+b
    5. // 1-b = mx
    6. // 1-b/m = x
    7. var lambda = (y - ray.Position.Y) / ray.Direction.Y;
    8. var xCoord = (double)(ray.Direction.X * lambda + ray.Position.X);
    9. var yCoord = (double)(ray.Direction.Y * lambda + ray.Position.Y);
    10. var zCoord = (double)(ray.Direction.Z * lambda + ray.Position.Z);
    11. return new Vector3((float)xCoord, (float)yCoord, (float)zCoord);
    12. }


    Ich bedanke mich bei Euch und insbesondere bei Rod!
    Bilder
    • Screenshot (237).png

      169,79 kB, 1.920×1.080, 148 mal angesehen
    Und Gott alleine weiß alles am allerbesten und besser.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „φConst“ ()

    φConst schrieb:

    0.00000026054704
    Das ist eine "float-Gammel-Null".
    Arbeite mal mit double.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Ich caste ja die einzelnen Komponenten in der Methode zu einem double.
    Es ist jedoch obligatorisch es wieder in float zu casten... die Klasse Vector3 nimmt als Parameter nur float an.
    Und Gott alleine weiß alles am allerbesten und besser.

    φConst schrieb:

    nur float
    Dann spiel ein wenig damit rum und lege einen hinreichend kleinen Wert fest, von dem Du annehmen kannst, dass ein Resultat (Betrag), der kleiner als dieser Wert ist, Null ist.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:
    Hallo, hab es folgendergestalt gelöst

    C#-Quellcode

    1. var yCoord = ray.Direction.Y * lambda + ray.Position.Y < 1E-5 ? 0 : ray.Direction.Y * lambda + ray.Position.Y;

    Nichtsdestotrotz danke ich euch beiden.
    Und Gott alleine weiß alles am allerbesten und besser.