RayTracing Teil 5: Dreiecke, Trapeze und Rauten als weitere ebene Primitive

Basierend auf dem Plane-Primitiv, welches eine unendlich ausgedehnte Ebene darstellt können wir mit wenig Aufwand weitere ebene Primitive implementieren. Zum Beispiel Rauten, Trapeze und Dreiecke. Alle diese Formen sind eben und stellen damit also nur einen Ausschnitt aus einem Plane-Primitiv dar. Wir können für jede dieser geometrischen Grundformen also eine neue Klasse erstellen, welche von Plane erbt, und überschreiben nur die Methode „RayTrace“. Die neuen „RayTrace“ Methoden werden zu der Methode „RayTrace“ aus der Plane Klasse sehr ähnlich implementiert: Wir berechnen wieder den Schnittpunkt des Rays mit der Ebene, welche von V und W aufgespannt wird. Anschließend prüfen wir jedoch noch zusätzlich, ob der Schnittpunkt auch innerhalb der Form liegt. Ist dies der Fall, geben wir einen PointOnPlane zurück, andernfalls den Wert null.

Das Raute-Primitiv

    public class Lozenge : Plane // Eine Raute, die von V und W aufgespannt wird
    {
        public Lozenge(Vector3D Origin, Vector3D V, Vector3D W, Color color) : base(Origin, V, W, color)
        {
        }

        public override PointOnPrimitive RayTrace(Ray ray)
        {
            double v;
            double w;
            double d;
            if (Vector3D.cramer(V, W, ray.Direction, ray.Start - Origin, out v, out w, out d))
            {
                if (w < 0 || w > 1) return null; // Schnittpunkt außerhalb Raute
                if (v < 0 || v > 1) return null; // Schnittpunkt außerhalb Raute
                if (-d > 0) return new PointOnPlane(v, w, this, -d);
            }
            return null; // Ray und Lozenge schneiden sich nicht
        }
    }

Das Dreieck-Primitiv

    public class Triangle : Plane // Ein Dreieck, das von V und W aufgespannt wird
    {
        public Triangle(Vector3D Origin, Vector3D V, Vector3D W, Color color) : base(Origin, V, W, color)
        {
        }

        public override PointOnPrimitive RayTrace(Ray ray)
        {
            double v;
            double w;
            double d;
            if (Vector3D.cramer(V, W, ray.Direction, ray.Start - Origin, out v, out w, out d))
            {
                if (v < 0 || w < 0 || v + w > 1) return null; // Schittpunkt zur Ebene außerhalb Dreieck
                if (-d > 0) return new PointOnPlane(v, w, this, -d);
            }
            return null; // Ray und Dreieck schneiden sich nicht
        }
    }

Das Trapez-Primitiv

    public class Trapezoid : Plane // Ein Trapez, das von der Grundseite V und einem Schenkel W aufgespannt wird
    {
        public Trapezoid(Vector3D Origin, Vector3D V, Vector3D W, Color color) : base(Origin, V, W, color)
        {
        }

        public override PointOnPrimitive RayTrace(Ray ray)
        {
            double v;
            double w;
            double d;
            if (Vector3D.cramer(V, W, ray.Direction, ray.Start - Origin, out v, out w, out d))
            {
                if (v < 0 || w < 0 || w > 1) return null;
                double bottomMinusTop = 2 * (V.normalize() * W) / V.length();
                double vmax = 1 - w * bottomMinusTop;
                if (v > vmax) return null;
                if (-d > 0) return new PointOnPlane(v, w, this, -d);
            }
            return null; // Ray und Trapez schneiden sich nicht
        }
    }

Weiter

Ein Gedanke zu „RayTracing Teil 5: Dreiecke, Trapeze und Rauten als weitere ebene Primitive

  1. Pingback: Raytracing Teil 4: Das Plane-Primitiv | Volkers Blog

Kommentare sind geschlossen.