예제 #1
0
 public bool ContainedIn(SimpleVolume otherArea)
 {
     if (MinX < otherArea.MinX || MaxX > otherArea.MaxX)
     {
         return(false);
     }
     if (MinY < otherArea.MinY || MaxY > otherArea.MaxY)
     {
         return(false);
     }
     if (MinZ < otherArea.MinZ || MaxZ > otherArea.MaxZ)
     {
         return(false);
     }
     return(true);
 }
예제 #2
0
 public bool Overlaps(SimpleVolume otherArea)
 {
     if (MaxX < otherArea.MinX || MinX > otherArea.MaxX)
     {
         return(false);
     }
     if (MaxY < otherArea.MinY || MinY > otherArea.MaxY)
     {
         return(false);
     }
     if (MaxZ < otherArea.MinZ || MinZ > otherArea.MaxZ)
     {
         return(false);
     }
     return(true);
 }
예제 #3
0
        public static bool IsInVolume(SimpleVolume volume, Point start, Point end)
        {
            if (volume.ContainsPoint(start) || volume.ContainsPoint(end))
            {
                return(true);
            }
            //Neither point is inside the volume. Check if any part of the line in between those points is inside the volume.
            if (!volume.Overlaps(ContainingVolume(start, end)))
            {
                return(false);                                                //Not even close
            }
            bool allInX = (start.x >= volume.MinX) && (end.x >= volume.MinX) && (start.x <= volume.MaxX) && (end.x <= volume.MaxX);
            bool allInY = (start.y >= volume.MinY) && (end.y >= volume.MinY) && (start.y <= volume.MaxY) && (end.y <= volume.MaxY);
            bool allInZ = (start.z >= volume.MinZ) && (end.z >= volume.MinZ) && (start.z <= volume.MaxZ) && (end.z <= volume.MaxZ);
            long rangeX = end.x - start.x; //promoting these to long to prevent overflow issues later
            long rangeY = end.y - start.y;
            long rangeZ = end.z - start.z;

            //note that rangeFoo == 0 implies allInFoo == true (else GetMaxVolume() check would have returned false),
            //and so allInFoo == false implies rangeFoo != 0

            if (!allInX)
            {     //Try X surfaces
                { //Try left surface
                    int diff = volume.MinX - start.x;
                    if (diff * rangeX < 0 || Math.Abs(diff) > Math.Abs(rangeX))
                    {
                        goto rightSurface;                                                         //This surface doesn't intersect.
                    }
                    if (!allInY)
                    {
                        int y = (int)(start.y + rangeY * diff / rangeX);
                        if (y < volume.MinY || y > volume.MaxY)
                        {
                            goto rightSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    if (!allInZ)
                    {
                        int z = (int)(start.z + rangeZ * diff / rangeX);
                        if (z < volume.MinZ || z > volume.MaxZ)
                        {
                            goto rightSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    return(true); //This line intersects with left surface.
                }
rightSurface:
                { //Try right surface
                    int diff = volume.MaxX - start.x;
                    if (diff * rangeX < 0 || Math.Abs(diff) > Math.Abs(rangeX))
                    {
                        goto foreSurface;                                                         //This surface doesn't intersect.
                    }
                    if (!allInY)
                    {
                        int y = (int)(start.y + rangeY * diff / rangeX);
                        if (y < volume.MinY || y > volume.MaxY)
                        {
                            goto foreSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    if (!allInZ)
                    {
                        int z = (int)(start.z + rangeZ * diff / rangeX);
                        if (z < volume.MinZ || z > volume.MaxZ)
                        {
                            goto foreSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    return(true); //This line intersects with right surface.
                }
            }
foreSurface:
            if (!allInY)
            {
                { //Try fore surface
                    int diff = volume.MinY - start.y;
                    if (diff * rangeY < 0 || Math.Abs(diff) > Math.Abs(rangeY))
                    {
                        goto backSurface;                                                         //This surface doesn't intersect.
                    }
                    if (!allInX)
                    {
                        int x = (int)(start.x + rangeX * diff / rangeY);
                        if (x < volume.MinX || x > volume.MaxX)
                        {
                            goto backSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    if (!allInZ)
                    {
                        int z = (int)(start.z + rangeZ * diff / rangeY);
                        if (z < volume.MinZ || z > volume.MaxZ)
                        {
                            goto backSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    return(true); //This line intersects with the fore surface.
                }
backSurface:
                {
                    int diff = volume.MaxY - start.y;
                    if (diff * rangeY < 0 || diff > rangeY)
                    {
                        goto bottomSurface;                                     //This surface doesn't intersect.
                    }
                    if (!allInX)
                    {
                        int x = (int)(start.x + rangeX * diff / rangeY);
                        if (x < volume.MinX || x > volume.MaxX)
                        {
                            goto bottomSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    if (!allInZ)
                    {
                        int z = (int)(start.z + rangeZ * diff / rangeY);
                        if (z < volume.MinZ || z > volume.MaxZ)
                        {
                            goto bottomSurface;                                     //This surface doesn't intersect.
                        }
                    }
                    return(true); //This line intersects with the back surface.
                }
            }
bottomSurface:
            if (allInZ)
            {
                return(false);
            }
            { //Try bottom surface
                int diff = volume.MinZ - start.z;
                if (diff * rangeZ < 0 || diff > rangeZ)
                {
                    goto topSurface;                                     //This surface doesn't intersect.
                }
                if (!allInX)
                {
                    int x = (int)(start.x + rangeX * diff / rangeZ);
                    if (x < volume.MinX || x > volume.MaxX)
                    {
                        goto topSurface;                                     //This surface doesn't intersect.
                    }
                }
                if (!allInY)
                {
                    int y = (int)(start.y + rangeY * diff / rangeZ);
                    if (y < volume.MinY || y > volume.MaxY)
                    {
                        goto topSurface;                                     //This surface doesn't intersect.
                    }
                }
                return(true); //This line intersects with the bottom surface.
            }
topSurface:
            return(false);
            //On second thought, we've checked all 5 other sides. The line can't go through only one surface
            //so it's safe to say this will never return true.
            //{
            //    int diff = volume.MaxY - Start.y;
            //    if (diff * rangeZ < 0 || diff > rangeZ) return false; //This surface doesn't intersect.
            //    if (!allInX)
            //    {
            //        int x = (int)(Start.x + rangeX * diff / rangeZ);
            //        if (x < volume.MinX || x > volume.MaxX) return false; //This surface doesn't intersect.
            //    }
            //    if (!allInY)
            //    {
            //        int y = (int)(Start.y + rangeY * diff / rangeZ);
            //        if (y < volume.MinY || y > volume.MaxY) return false; //This surface doesn't intersect.
            //    }
            //    return true; //This line intersects with the top surface.
            //}
        }