矩形交点

发布于 2024-12-21 10:46:26 字数 619 浏览 5 评论 0 原文

我有一个矩形列表,我需要生成一个相交的矩形列表。
定义矩形

  • 使用Point
  • Size
  • Boolean 矩形是否可以移动
  • Boolean 矩形是否可以移除 矩形

不能移动但不能移除

交集使用 Point Size 定义 交点使用

  • 指向第一个矩形的
  • 指针 指向第二个矩形的指针
  • 第一个矩形的点列表 第二个列表中
  • 在第一个矩形中第二个矩形的点的

,我需要一个容器,因为可以添加、删除或移动矩形。我需要的操作:

  1. 插入矩形
  2. 删除矩形(仅适用于那些标记了它的人)
  3. 更改矩形的位置(不是大小,仅适用于那些标记了它的人)
  4. 生成交集集。

我将如何实施这样的容器?我可以使用交叉检查方法轻松完成此操作,但这远未达到优化。
我想保留一张矩形地图 ->交集,然后每当添加一个矩形时,检查它是否与任何东西相交并将交集添加到地图中,当删除它时,从地图上删除键,但我不知道如何快速检查它是否与任何东西相交,或者如何移动矩形而不删除并重新插入。
我可以使用 C++11。

I have a list of rectangles and I need to generate a list of rectangles that intersect.
Rectangles are defined using

  • Point
  • Size
  • Boolean whether the rectangle can move
  • Boolean whether the rectangle can be removed

No rectangles can be moved but cannot be removed

An intersection is defined using

  • Pointer to first rectangle
  • Pointer to second rectangle
  • List of points of the first rectangle that are in the second
  • List of points of the second rectangle that are in the first

I need a container for this, as rectangles can be added, removed or moved. operations that I need:

  1. Insert of rectangle
  2. Remove of rectangle (only possible for those who are marked for it)
  3. Changing position of rectangle (not size, only possible with those who are marked for it)
  4. Generating set of intersections.

How would I go about implementing such a container? I can do it easily using cross check method, but that will be far from optimized.
I thought of keeping a map of rectangle -> intersection and then whenever a rectangle is added check if its intersecting anything and add intersection to the map, and when its removed, remove the key from the map, but I don't know how to check if it intersects anything fast, or how to move rectangles without remove and reinsert.
I can use C++11.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

高跟鞋的旋律 2024-12-28 10:46:26

假设从左到右/从上到下的坐标系,两个矩形的交集就是顶部是顶部中最底部的矩形,底部是底部中最顶部的矩形,左如果是左和右中最右的是最左边的权利。

如果您可以通过按左、上、右和下排序的容器间接访问矩形,则可以有效地运行测试。

另一种方法可以是使用一个键(对于映射),该键是 ax/delta 对以及运算符<<。在 a.x+a.delta a.x+a.delta 的地方考虑 a bx 和 y 相同。
原始点只是一个大小为 1 的矩形。

本质上,您需要一个矩形本身的容器(修改时不得重新分配矩形,因此 std::list 可以工作)和两个 std::map(用于水平和垂直)映射)具有位置/大小对作为键和列表迭代器(可以是由 &*iter 生成的矩形指针)作为值。

Assuming a left-to-right / top-to-bottom coordinate system, the intersection of two rectangles is the rectangle whose top is the bottomest of the tops, bottom is the toppest of the bottoms, left if the rightest of the lefts and right is the leftest of the rights.

You can efficiently run the tests if you can indirectly access the rectangles by containers that are sorted by left, top, right and bottom.

An alternative can be using a key (for the map) that is a x/delta pair with an operator< that consider a<b wherever a.x+a.delta < b.x and same for the y.
A raw point is just a rectangle of size 1.

In essence, you need a container for the rectangle themselves (must not reallocate rectangles when modified, hence a std::list can work) and two std::maps (for horz and vert mapping) having a place/size pairs as key and a list iterator (can be a rectangle pointer resulting from &*iter) as value.

玩世 2024-12-28 10:46:26

我的建议是一个模糊的容器:

class region {
    typedef std::vector<vector*> subregion;
    std::array<std::array<subregion, 100>, 100> locations;
    std::vector<rectangle> children;
public:
    std::vector<rectangle>::iterator add(rectangle addme);
    void remove(std::vector<rectangle>::iterator deleteme);
    void move(std::vector<rectangle>::iterator moveme, point to);
    void intersect(std::vector<rectangle>::iterator left, 
                   std::vector<rectangle>::iterator right);
};

children 成员只是容器中矩形的迭代列表。每个子区域是可容纳矩形的总区域的百分之一。添加矩形后,指向它的指针将添加到该矩形接触的所有子区域。当删除矩形时,它的指针将从该矩形接触的所有子区域中删除。移动实际上是删除、矩形更新,然后添加。

然后,要找到交集(取决于您想要的方式),您只需查看包含多个指针的每个子区域,并对该子区域中的每个矩形进行简单比较。

My recommendation would be a container vaguely like:

class region {
    typedef std::vector<vector*> subregion;
    std::array<std::array<subregion, 100>, 100> locations;
    std::vector<rectangle> children;
public:
    std::vector<rectangle>::iterator add(rectangle addme);
    void remove(std::vector<rectangle>::iterator deleteme);
    void move(std::vector<rectangle>::iterator moveme, point to);
    void intersect(std::vector<rectangle>::iterator left, 
                   std::vector<rectangle>::iterator right);
};

The children member is merely an iterative list of rectangles in the container. Each subregion is one-onehundredth of the total region that can hold rectangles. When a rectangle is added, pointers to it are added to all sub-regions that the rectangle touches. When a rectangle is removed, it's pointers are removed from all sub-regions that the rectangle touches. A move is effectively a removal, rectangle update, then an add.

Then, to find intersections (depending on how you want them), you simply look at each subregion that contains more than one pointer, and do a simple comparison of each of the rectangles in that subregion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文