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); }
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); }
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. //} }