Ejemplo n.º 1
0
 public IntrPlane3Plane3(Plane3d p0, Plane3d p1)
 {
     plane0 = p0;
     plane1 = p1;
 }
Ejemplo n.º 2
0
 public IntrLine3Plane3(Line3d l, Plane3d p)
 {
     line  = l;
     plane = p;
 }
        public bool Find()
        {
            if (Result != IntersectionResult.NotComputed)
            {
                return(Result != g3.IntersectionResult.NoIntersection);
            }


            // in this code the results get initialized in subroutines, so we
            // set the defautl value here...
            Result = IntersectionResult.NoIntersection;


            int i, iM, iP;

            // Get the plane of triangle0.
            Plane3d plane0 = new Plane3d(triangle0.V0, triangle0.V1, triangle0.V2);

            // Compute the signed distances of triangle1 vertices to plane0.  Use
            // an epsilon-thick plane test.
            int      pos1, neg1, zero1;
            Index3i  sign1;
            Vector3d dist1;

            TrianglePlaneRelations(ref triangle1, ref plane0, out dist1, out sign1, out pos1, out neg1, out zero1);

            if (pos1 == 3 || neg1 == 3)
            {
                // Triangle1 is fully on one side of plane0.
                return(false);
            }

            if (zero1 == 3)
            {
                // Triangle1 is contained by plane0.
                if (ReportCoplanarIntersection)
                {
                    return(GetCoplanarIntersection(ref plane0, ref triangle0, ref triangle1));
                }
                return(false);
            }

            // Check for grazing contact between triangle1 and plane0.
            if (pos1 == 0 || neg1 == 0)
            {
                if (zero1 == 2)
                {
                    // An edge of triangle1 is in plane0.
                    for (i = 0; i < 3; ++i)
                    {
                        if (sign1[i] != 0)
                        {
                            iM = (i + 2) % 3;
                            iP = (i + 1) % 3;
                            return(IntersectsSegment(ref plane0, ref triangle0, triangle1[iM], triangle1[iP]));
                        }
                    }
                }
                else    // zero1 == 1
                // A vertex of triangle1 is in plane0.
                {
                    for (i = 0; i < 3; ++i)
                    {
                        if (sign1[i] == 0)
                        {
                            return(ContainsPoint(ref triangle0, ref plane0, triangle1[i]));
                        }
                    }
                }
            }

            // At this point, triangle1 tranversely intersects plane 0.  Compute the
            // line segment of intersection.  Then test for intersection between this
            // segment and triangle 0.
            double   t;
            Vector3d intr0, intr1;

            if (zero1 == 0)
            {
                int iSign = (pos1 == 1 ? +1 : -1);
                for (i = 0; i < 3; ++i)
                {
                    if (sign1[i] == iSign)
                    {
                        iM    = (i + 2) % 3;
                        iP    = (i + 1) % 3;
                        t     = dist1[i] / (dist1[i] - dist1[iM]);
                        intr0 = triangle1[i] + t * (triangle1[iM] - triangle1[i]);
                        t     = dist1[i] / (dist1[i] - dist1[iP]);
                        intr1 = triangle1[i] + t * (triangle1[iP] - triangle1[i]);
                        return(IntersectsSegment(ref plane0, ref triangle0, intr0, intr1));
                    }
                }
            }

            // zero1 == 1
            for (i = 0; i < 3; ++i)
            {
                if (sign1[i] == 0)
                {
                    iM    = (i + 2) % 3;
                    iP    = (i + 1) % 3;
                    t     = dist1[iM] / (dist1[iM] - dist1[iP]);
                    intr0 = triangle1[iM] + t * (triangle1[iP] - triangle1[iM]);
                    return(IntersectsSegment(ref plane0, ref triangle0, triangle1[i], intr0));
                }
            }

            // should never get here...
            Debug.Assert(false);
            return(false);
        }
        bool GetCoplanarIntersection(ref Plane3d plane, ref Triangle3d tri0, ref Triangle3d tri1)
        {
            // Project triangles onto coordinate plane most aligned with plane
            // normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri0 = new Triangle2d(), projTri1 = new Triangle2d();
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].yz;
                    projTri1[i] = tri1[i].yz;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xz;
                    projTri1[i] = tri1[i].xz;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri0[i] = tri0[i].xy;
                    projTri1[i] = tri1[i].xy;
                }
            }

            // 2D triangle intersection routines require counterclockwise ordering.
            Vector2d save;
            Vector2d edge0 = projTri0[1] - projTri0[0];
            Vector2d edge1 = projTri0[2] - projTri0[0];

            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri0[1];
                projTri0[1] = projTri0[2];
                projTri0[2] = save;
            }

            edge0 = projTri1[1] - projTri1[0];
            edge1 = projTri1[2] - projTri1[0];
            if (edge0.DotPerp(edge1) < (double)0)
            {
                // Triangle is clockwise, reorder it.
                save        = projTri1[1];
                projTri1[1] = projTri1[2];
                projTri1[2] = save;
            }

            IntrTriangle2Triangle2 intr = new IntrTriangle2Triangle2(projTri0, projTri1);

            if (!intr.Find())
            {
                return(false);
            }

            PolygonPoints = new Vector3d[intr.Quantity];

            // Map 2D intersections back to the 3D triangle space.
            Quantity = intr.Quantity;
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; i++)
                {
                    double y = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double z = intr.Points[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; i++)
                {
                    double x = intr.Points[i].x;
                    double y = intr.Points[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    PolygonPoints[i] = new Vector3d(x, y, z);
                }
            }

            Result = IntersectionResult.Intersects;
            Type   = IntersectionType.Polygon;
            return(true);
        }
        bool IntersectsSegment(ref Plane3d plane, ref Triangle3d triangle, Vector3d end0, Vector3d end1)
        {
            // Compute the 2D representations of the triangle vertices and the
            // segment endpoints relative to the plane of the triangle.  Then
            // compute the intersection in the 2D space.

            // Project the triangle and segment onto the coordinate plane most
            // aligned with the plane normal.
            int    maxNormal = 0;
            double fmax      = Math.Abs(plane.Normal.x);
            double absMax    = Math.Abs(plane.Normal.y);

            if (absMax > fmax)
            {
                maxNormal = 1;
                fmax      = absMax;
            }
            absMax = Math.Abs(plane.Normal.z);
            if (absMax > fmax)
            {
                maxNormal = 2;
            }

            Triangle2d projTri = new Triangle2d();
            Vector2d   projEnd0 = Vector2d.Zero, projEnd1 = Vector2d.Zero;
            int        i;

            if (maxNormal == 0)
            {
                // Project onto yz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].yz;
                    projEnd0.x = end0.y;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.y;
                    projEnd1.y = end1.z;
                }
            }
            else if (maxNormal == 1)
            {
                // Project onto xz-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xz;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.z;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.z;
                }
            }
            else
            {
                // Project onto xy-plane.
                for (i = 0; i < 3; ++i)
                {
                    projTri[i] = triangle[i].xy;
                    projEnd0.x = end0.x;
                    projEnd0.y = end0.y;
                    projEnd1.x = end1.x;
                    projEnd1.y = end1.y;
                }
            }

            Segment2d             projSeg = new Segment2d(projEnd0, projEnd1);
            IntrSegment2Triangle2 calc    = new IntrSegment2Triangle2(projSeg, projTri);

            if (!calc.Find())
            {
                return(false);
            }

            Vector2dTuple2 intr = new Vector2dTuple2();

            if (calc.Type == IntersectionType.Segment)
            {
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Segment;
                Quantity = 2;
                intr.V0  = calc.Point0;
                intr.V1  = calc.Point1;
            }
            else
            {
                Debug.Assert(calc.Type == IntersectionType.Point);
                //"Intersection must be a point\n";
                Result   = IntersectionResult.Intersects;
                Type     = IntersectionType.Point;
                Quantity = 1;
                intr.V0  = calc.Point0;
            }

            // Unproject the segment of intersection.
            if (maxNormal == 0)
            {
                double invNX = ((double)1) / plane.Normal.x;
                for (i = 0; i < Quantity; ++i)
                {
                    double y = intr[i].x;
                    double z = intr[i].y;
                    double x = invNX * (plane.Constant - plane.Normal.y * y - plane.Normal.z * z);
                    Points[i] = new Vector3d(x, y, z);
                }
            }
            else if (maxNormal == 1)
            {
                double invNY = ((double)1) / plane.Normal.y;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double z = intr[i].y;
                    double y = invNY * (plane.Constant - plane.Normal.x * x - plane.Normal.z * z);
                    Points[i] = new Vector3d(x, y, z);
                }
            }
            else
            {
                double invNZ = ((double)1) / plane.Normal.z;
                for (i = 0; i < Quantity; ++i)
                {
                    double x = intr[i].x;
                    double y = intr[i].y;
                    double z = invNZ * (plane.Constant - plane.Normal.x * x - plane.Normal.y * y);
                    Points[i] = new Vector3d(x, y, z);
                }
            }

            return(true);
        }
Ejemplo n.º 6
0
 public IntrRay3Plane3(Ray3d r, Plane3d p)
 {
     ray   = r;
     plane = p;
 }