Reputation: 33
I have a xy plane containing a series of alphabetically named non-overlapping rectangular regions defined by 2 corners each as Point3d's (z-dimension is immaterial here, they are outputted by api as point3ds).
How can I best find which region a random point3d lays within?
Also, how could I check to make sure the regions are infact not overlapping?
Thanks!
Upvotes: 0
Views: 54
Reputation: 37020
Without code to represent your objects, it's a little difficult to answer, but here's an example using a Region
struct that contains two Point
properties (which I assume are similar to your Point3d
classes except there's no Z
, which you said is irrelevant).
First, I would include a property that represents the region as a Rectangle
, since it has most of the functionality you already need. I would also include methods that tell you if a Region
contains a Point
, if one Region
instance overlaps another Region
, and a method that tells you if any Region
in a list overlaps another in the list:
public struct Region
{
public Point Corner1 { get; }
public Point Corner2 { get; }
public Rectangle Rectangle { get; }
public Region(Point corner1, Point corner2)
{
Corner1 = corner1;
Corner2 = corner2;
var leftMost = Math.Min(Corner1.X, Corner2.X);
var topMost = Math.Min(Corner1.Y, Corner2.Y);
var width = Math.Abs(Corner1.X - Corner2.X);
var height = Math.Abs(Corner1.Y - Corner2.Y);
Rectangle = new Rectangle(leftMost, topMost, width, height);
}
public static bool AnyOverlap(List<Region> regions)
{
if (regions == null || regions.Count == 1) return false;
for (int i = 0; i < regions.Count - 1; i++)
{
for (int j = i + 1; j < regions.Count; j++)
{
if (regions[i].Overlaps(regions[j]))
{
return true;
}
}
}
return false;
}
public bool Contains(Point p)
{
return p.X >= Rectangle.Left && p.X <= Rectangle.Right &&
p.Y >= Rectangle.Top && p.Y <= Rectangle.Bottom;
}
public bool Overlaps(Region other)
{
return Rectangle.Left < other.Rectangle.Right &&
Rectangle.Right > other.Rectangle.Left &&
Rectangle.Top > other.Rectangle.Bottom &&
Rectangle.Bottom < other.Rectangle.Top;
}
public override bool Equals(object obj)
{
return obj is Region && Rectangle.Equals(((Region) obj).Rectangle);
}
public override int GetHashCode()
{
return Rectangle.GetHashCode();
}
}
With this, if you have a List<Region> xyPlane
, you can do:
Point randomPoint = new Point(20, 30);
bool anyRegionsOverlap = Region.AnyOverlap(xyPlane);
Region containsPoint = xyPlane.FirstOrDefault(region =>
region.Contains(randomPoint));
Upvotes: 1