我正在实施Moller计算三角形三角形交叉的算法,我不能完全绕过某些东西:给定交叉三角形的两个平面,我们有相应的方程,形式为N * P d = 0,其中N是十字形在平面上产生两个向量,P是平面上的任何点 . d也可以计算 .

考虑到三角形不是共面的,它们的交点将是一条线L = P tD,其中D是N(第一平面)* N(第二平面) - 这是线的方向,P是线上的任何点和t是参数 . 该算法停止计算三角形的交叉区段与它们的相对三角形平面的t . 现在,如果这些段重叠,则三角形相交 . 但同样,这些细分仅以t表示 . 然而,我想要更进一步,实际上得到交叉点的坐标 .

所以这里有一个问题 - 给定两个平面,三个点位于平面上(三角形的点)和线L = P tD我们知道D和ts,我怎样才能计算出这些点的点?

非常感谢任何帮助,谢谢

我正在添加到目前为止我所获得的代码:{// Tomas Moller的剖面搜索算法的增加以确定交叉点的coorninates

//Vertex vectors
    Vector3f Va0(a.Point1.X, a.Point1.Y, a.Point1.Z);
    Vector3f Va1(a.Point2.X, a.Point2.Y, a.Point2.Z);
    Vector3f Va2(a.Point3.X, a.Point3.Y, a.Point3.Z);

    Vector3f Vb0(b.Point1.X, b.Point1.Y, b.Point1.Z);
    Vector3f Vb1(b.Point2.X, b.Point2.Y, b.Point2.Z);
    Vector3f Vb2(b.Point3.X, b.Point3.Y, b.Point3.Z);

    //First, find the plane equation of triangle b = Pb
    //N dot X + d = 0 where X is any point on the plane
    auto N2 = (Vb1 - Vb0).cross((Vb2 - Vb0));
    N2.normalize();
    float d2 = (N2 * (-1)).dot(Vb0);

    //We'll then find the signed distance from each point of the triangle a to plane Pb
    float da_0 = Round(N2.dot(Va0) + d2);
    float da_1 = Round(N2.dot(Va1) + d2);
    float da_2 = Round(N2.dot(Va2) + d2);

    //reject intersetion if none of the points lie on the plane and all have the same sign
    //meaning that the triangle a lies on one side of the triangle b
    if (da_0 != 0 && da_1 != 0 && da_2 != 0 && da_0 > 0 && da_1 > 0 && da_2 > 0)
        return nullptr;
    if (da_0 != 0 && da_1 != 0 && da_2 != 0 && da_0 < 0 && da_1 < 0 && da_2 < 0)
        return nullptr;

    //do the same thing for the other triangle
    auto N1 = (Va1 - Va0).cross((Va2 - Va0));
    N1.normalize();
    float d1 = (N1 * (-1)).dot(Va0);

    float db_0 = Round(N1.dot(Vb0) + d1);
    float db_1 = Round(N1.dot(Vb1) + d1);
    float db_2 = Round(N1.dot(Vb2) + d1);

    if (db_0 != 0 && db_1 != 0 && db_2 != 0 && db_0 > 0 && db_1 > 0 && db_2 > 0)
        return nullptr;
    if (db_0 != 0 && db_1 != 0 && db_2 != 0 && db_0 < 0 && db_1 < 0 && db_2 < 0)
        return nullptr;

    #pragma region Coplanar Triangles
    if (db_0 == 0 && db_1 == 0 && db_2 == 0)
    {
        //if the triangles are coplanar we'll find the intersection in 2d space
        return nullptr;
    }
    #pragma endregion

    #pragma region Triangles are in 3D space
    else
    {
        //Triangles are not coplanar and the intersection line is some line L = O + tD 
        //where D = N1 cross N2 - direction of the line and O is some point on it
        //We will find the the intersection segment of the first triangle with the plane os the second triangle and visa versa
        //If the two segments overlap, the triangles intesect

        auto D = N1.cross(N2);
        D.normalize();

        #pragma region Point Contact Between the Triangles
        //first reject intersection if one triangle only touches the other with one point
        if ((da_0 == 0 && da_1 > 0 && da_2 > 0) || (da_0 == 0 && da_1 < 0 && da_2 < 0))
            return nullptr;
        if ((da_0 > 0 && da_1 == 0 && da_2 > 0) || (da_0 < 0 && da_1 == 0 && da_2 < 0))
            return nullptr;
        if ((da_0 > 0 && da_1 > 0 && da_2 == 0) || (0 > da_0 && da_1 < 0 && da_2 == 0))
            return nullptr;
        if ((db_0 == 0 && db_1 > 0 && db_2 > 0) || (db_0 == 0 && db_1 < 0 && db_2 < 0))
            return nullptr;
        if ((db_0 > 0 && db_1 == 0 && db_2 > 0) || (db_0 < 0 && db_1 == 0 && db_2 < 0))
            return nullptr;
        if ((db_0 > 0 && db_1 > 0 && db_2 == 0) || (0 > db_0 && db_1 < 0 && db_2 == 0))
            return nullptr;
        #pragma endregion

        //If the above passes, proceed with 3d triangle intersection. Start with triangle a and plane Pb,
        //there will be one point of a on one side of the Pb and two points of a on the other side of Pb. Let's find them:
        #pragma region Triangle A
        tuple<Vector3f, Vector3f> edgeA1;
        tuple<Vector3f, Vector3f> edgeA2;
        float dV0 = 1;
        float dV1 = 1;
        float dV2 = 1;

        if ((da_0 > 0 && da_1 <= 0 && da_2 <= 0) || (da_0 < 0 && da_1 >= 0 && da_2 >= 0))
        {
            edgeA1 = make_tuple(Va1, Va0);
            edgeA2 = make_tuple(Va0, Va2);
            dV0 = da_1;
            dV1 = da_0;
            dV2 = da_2;
        }
        else if ((da_0 <= 0 && da_1 > 0 && da_2 <= 0) || (da_0 >= 0 && da_1 < 0 && da_2 >= 0))
        {
            edgeA1 = make_tuple(Va0, Va1);
            edgeA2 = make_tuple(Va1, Va2);
            dV0 = da_0;
            dV1 = da_1;
            dV2 = da_2;
        }
        else if ((da_0 <= 0 && da_1 <= 0 && da_2 > 0) || (da_0 >= 0 && da_1 >= 0 && da_2 < 0))
        {
            edgeA1 = make_tuple(Va0, Va2);
            edgeA2 = make_tuple(Va2, Va1);
            dV0 = da_0;
            dV1 = da_2;
            dV2 = da_1;
        }

        //pi = D * Vi where i = 0, 1, 2
        auto pA_0 = D.dot(get<0>(edgeA1));
        auto pA_1 = D.dot(get<0>(edgeA2));
        auto pA_2 = D.dot(get<1>(edgeA2));

        //The tA_1 and tA_2 define the interval of the intersection of triangle a with the line L
        float tA_1 = pA_0 + (pA_1 - pA_0) * (dV0 / (dV0 - dV1));
        float tA_2 = pA_1 + (pA_2 - pA_1) * (dV1 / (dV1 - dV2));
        #pragma endregion

        //Now repeat for triangle b
        #pragma region Triangle B
        tuple<Vector3f, Vector3f> edgeB1;
        tuple<Vector3f, Vector3f> edgeB2;

        if ((db_0 > 0 && db_1 <= 0 && db_2 <= 0) || (db_0 < 0 && db_1 >= 0 && db_2 >= 0))
        {
            edgeB1 = make_tuple(Vb1, Vb0);
            edgeB2 = make_tuple(Vb0, Vb2);
            dV0 = db_1;
            dV1 = db_0;
            dV2 = db_2;
        }
        else if ((db_0 <= 0 && db_1 > 0 && db_2 <= 0) || (db_0 >= 0 && db_1 < 0 && db_2 >= 0))
        {
            edgeB1 = make_tuple(Vb0, Vb1);
            edgeB2 = make_tuple(Vb1, Vb2);
            dV0 = db_0;
            dV1 = db_1;
            dV2 = db_2;
        }
        else if ((db_0 <= 0 && db_1 <= 0 && db_2 > 0) || (db_0 >= 0 && db_1 >= 0 && db_2 < 0))
        {
            edgeB1 = make_tuple(Vb0, Vb2);
            edgeB2 = make_tuple(Vb2, Vb1);
            dV0 = db_0;
            dV1 = db_2;
            dV2 = db_1;
        }

        //pi = D * Vi where i = 0, 1, 2
        auto pB_0 = D.dot(get<0>(edgeB1));
        auto pB_1 = D.dot(get<0>(edgeB2));
        auto pB_2 = D.dot(get<1>(edgeB2));

        //The tA_1 and tA_2 define the interval of the intersection of triangle a with the line L
        float tB_1 = pB_0 + (pB_1 - pB_0) * (dV0 / (dV0 - dV1));
        float tB_2 = pB_1 + (pB_2 - pB_1) * (dV1 / (dV1 - dV2));
        #pragma endregion

        #pragma region Determine Overlap
        bool intersect = false;
        float intPoint1;
        float intPoint2;

        //Order the segments
        if (tA_1 > tA_2)
        {
            float temp = tA_1;
            tA_1 = tA_2;
            tA_2 = temp;
        }
        if (tB_1 > tB_2)
        {
            float temp = tB_1;
            tB_1 = tB_2;
            tB_2 = temp;
        }

        //Check for overlap
        if (tB_1 >= tA_1 && tB_2 <= tA_2)
        {
            intPoint1 = tB_1;
            intPoint2 = tB_2;
            intersect = true;
        }
        else if (tA_1 >= tB_1 && tA_2 <= tB_2)
        {
            intPoint1 = tA_1;
            intPoint2 = tA_2;
            intersect = true;
        }
        else if (tB_1 >= tA_1 && tB_1 < tA_2 && tB_2 > tA_2)
        {
            intPoint1 = tB_1;
            intPoint2 = tA_2;
            intersect = true;
        }
        else if (tA_1 >= tB_1 && tA_1 < tB_2 && tA_2 > tB_2)
        {
            intPoint1 = tA_1;
            intPoint2 = tB_2;
            intersect = true;
        }
        #pragma endregion

        if (!intersect)
            return nullptr;

        //If an overlap found, perform the last step of the algorithm and find the actual points of the intersection segment
        else
        {

        }
    }
    #pragma endregion 
}