1

我正在尝试编写一个应用程序来绘制包含矩形、线条和圆形的示意图。现在我想添加另一个功能来将矩形拖动到不同的位置。我面临的问题是检测我是否在矩形内单击过。我知道有一个像Rectangle.Contains(Point). 要使用这种方法,我需要使用 for 循环来检查每个矩形。如果我有大量的矩形,那么使用这种方法是不明智的。有没有其他方法可以完成这项任务。

4

4 回答 4

3

你需要一本计算机图形学教科书,经常讨论这个和类似的问题。

如果没记错的话,请确保该点位于矩形顶部边缘下方、底部边缘上方、右侧边缘左侧和左侧边缘右侧。

关于在循环中测试一堆矩形。考虑有一个每个矩形都适合的圆,一个边界圆。首先测试该点是否比圆的半径更远。如果是这样,则无需测试矩形,那就是错过了。好的,这是一个非常理论的答案。实际上计算点到原点的距离可能是一个非常昂贵的计算,它涉及一个平方根,在矩形检查中进行点的四次比较可能会更快。同样,如果内存为我服务,我们并不真正关心与原点的距离是多少,只有当它大于半径时。所以只执行部分距离计算,省略最终的平方根,并与半径的平方进行比较。并且您需要确保您将有足够的未命中来抵消最终会同时进行边界圆和矩形检查的命中。

于 2012-07-26T05:36:10.163 回答
1

您需要使用空间索引来快速找到鼠标在哪个矩形中。我建议使用 R-tree,这是理论部分:

http://en.wikipedia.org/wiki/R-tree

而c#,实现:

http://sourceforge.net/projects/cspatialindexrt/

创建一个 rtee,添加您的矩形,然后使用鼠标坐标调用 rtree.nearest 方法以了解包含鼠标光标的矩形。您可以使用距离参数。

希望能帮助到你,

安本潘格罗斯。

于 2014-09-30T20:04:36.600 回答
0

我会将显示区域划分为一个象限。然后将矩形放入左上角、右上角、左下角、右下角的网格中。放置它们意味着为每个象限创建一个列表并将矩形放置在其中。

单击该点后,确定它属于哪个季度并仅在这些矩形中搜索。这种方法将您的线性搜索减少了 4 倍。

请记住,您还需要注意重叠点可以属于许多矩形。在这里,矩形的 z 顺序很重要。因此,虽然列表是为一个象限维护的,但它应该以它的 z 顺序作为键进行排序。

希望这可以帮助。

于 2012-07-26T05:11:57.397 回答
0

可能是这样的吗?

 public bool isRectangelContainPoint(RectangleF rec, PointF pt)
    {
        if (pt.X >= rec.Left && pt.X <= rec.Right && pt.Y <= rec.Bottom && pt.Y >= rec.Top)
            return true;
        else
            return false;
    }
于 2014-09-28T03:53:59.073 回答