Ejemplo n.º 1
0
Triangle::Triangle(const Triangle & t):
    m_a(t.A()),
    m_b(t.B()),
    m_c(t.C()),
    m_interpolatedNormales(t.interpolatedNormales())
{
}
Ejemplo n.º 2
0
/**
 * Prueft ob der Strahl ray die Ebene, welche durch das Dreieck
 * triangle definiert ist, schneidet.
 * @param ray Zu testender Strahl
 * @param triangle Dreieck das die Ebene beschreibt
 * @param result Ergebnisvektor: Schneidet der Strahl die Ebene
 * liegt das Ergebnis in result vor
 * @pre result Muss auf ein existierendes Vektor-Objekt zeigen
 */
bool Triangle::rayIntersectsPlane(const Ray &ray,
                                  const Triangle &triangle,
                                  Vector3D *result) const
{
    bool bResult = false;

    // Zwei Seiten des Dreieck fuer die Normalenvektorberechnung
    Vector3D ab(triangle[1] - triangle[0]);
    Vector3D ac(triangle[2] - triangle[0]);
    // Normalenvektor der Ebene, Kreuzprodukt ab x ac
    Vector3D n(ab.crossProduct(ac));
    // Konstante aus der Ebenengleichung in Normalform
    // e: n * (x,y,z) + c = 0
    VTYPE c = n * triangle.A();

    // Ortsvektor des Strahls
    Vector3D o(ray.point);
    // Richtungsvektor des Strahls
    Vector3D d(ray.dir);

    // Geradenparameter t erhaelt man durch Einsetzen der
    // Geradengleichung in die Ebenengleichung(Normalform)
    VTYPE t_denominator = n[0]*d[0] + n[1]*d[1] + n[2]*d[2];

    // Der Nenner muss gueltig(!=0) sein
    if (!IS_EQUAL(t_denominator, 0))
    {
        // Minuszeichen extrahiert, um Gleitkommazahlenungenauigkeit durch
        // Subtraktionen zu verhinden
        VTYPE t_numerator = n[0]*o[0] + n[1]*o[1] + n[2]*o[2] - c;
        VTYPE t = t_numerator / t_denominator;

        // Das extrahierte Minuszeichen wird hier durch Umkehren des
        // > Operators beruecksichtigt. Statt t>=0, also -t<=0.
        // Da jedoch bei rekursivem Raytracing die Strahlen ihren Ursprung auf Objekt-
        // oberflachen haben, muss t != 0 sein, da ansonsten sofort wieder ein
        // Schnittpunkt im Strahlenursprung festgestellt werden wuerde.
        if (IS_SMALLER(t,0)) // Ebene darf nicht hinter dem Strahl liegen
        {
            // Schnittpunkt durch Einsetzen von t in Geradengleichung
            // Auch hier muss wieder das extrahierte Minuszeichen beachtet werden
            *result = o + d * -t;
            bResult = true;
        }
    }

    return bResult;
}