首页 > 解决方案 > 在具有定义区域的网格上确定 Point3d 的位置

问题描述

我有一个 xy 平面,其中包含一系列按字母顺序命名的非重叠矩形区域,每个区域由 2 个角定义为 Point3d(z 维度在这里无关紧要,它们由 api 输出为 point3ds)。

我怎样才能最好地找到随机 point3d 所在的区域?

另外,我如何检查以确保这些区域实际上没有重叠?

谢谢!

标签: c#.net

解决方案


如果没有代码来表示您的对象,回答起来有点困难,但这是一个使用Region包含两个Point属性的结构的示例(我假设它与您的类相似,Point3d除了没有Z,您说这无关紧要)。

首先,我将包含一个将区域表示为 的属性Rectangle,因为它具有您已经需要的大部分功能。我还将包括告诉您 a 是否Region包含 a Point,一个Region实例是否与另一个 重叠Region的方法,以及一个告诉您列表中是否有任何Region与列表中的另一个重叠的方法:

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();
    }
}

有了这个,如果你有一个List<Region> xyPlane,你可以这样做:

Point randomPoint = new Point(20, 30);

bool anyRegionsOverlap = Region.AnyOverlap(xyPlane);
Region containsPoint = xyPlane.FirstOrDefault(region =>
    region.Contains(randomPoint));

推荐阅读