他们决定不在Android中添加contains方法(用于Path)的原因是什么?
我想知道我在路径中有哪些点,并希望它比这里看到的更容易:
How can I tell if a closed path contains a given point?
如果我创建一个ArrayList并将整数添加到数组中会更好吗?(我只在控制语句中检查一次点)即。if(myPath.contains(x,y)
到目前为止,我的选择是:
- 使用区域
- 使用ArrayList
- 扩展类
- 你的建议
我只是在寻找最有效的方法
4条答案
按热度按时间laximzn51#
不久前,我遇到了同样的问题,经过一番搜索,我发现这是最好的解决方案。
Java有一个
Polygon
类,它有一个contains()
方法,可以让事情变得非常简单。不幸的是,java.awt.Polygon
类在Android中不受支持。但是,我能够找到一个写了一个等效类的人。我不认为你可以从Android
Path
类中获取组成路径的各个点,所以你必须以不同的方式存储数据。该类使用交叉数算法来确定点是否在给定的点列表中。
rdrgkggo2#
我只想评论@theisenp的回答:该代码有整数数组,如果你看算法描述网页,它警告不要使用整数而不是浮点数。
我复制了你上面的代码,它似乎工作得很好,除了一些角落的情况下,当我做的线,没有连接到自己很好。
通过将所有内容都改为浮点,我摆脱了这个bug。
o2g1uqev3#
我尝试了另一个答案,但它给了我一个错误的结果。没有费心去寻找确切的原因,但我自己直接从算法翻译:http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html
现在代码如下:
cnjp1d6j4#
为了完整起见,我想在这里做几点说明:
从API 19开始,路径有一个交集操作。你可以在你的测试点周围创建一个非常小的正方形路径,将它与Path相交,看看结果是否为空。
您可以将路径转换为区域并执行contains()操作。然而,区域在整数坐标下工作,我认为它们使用转换后的(像素)坐标,所以你必须使用它。我还怀疑转换过程是计算密集型的。
Hans发布的边交叉算法很好,速度也很快,但对于某些角点情况,例如光线直接穿过顶点或与水平边相交时,或者舍入误差是一个问题时,你必须非常小心。
缠绕数方法是相当愚蠢的证明,但涉及到大量的计算量和计算成本。
This paper by Dan Sunday给出了一种混合算法,它与缠绕数一样精确,但计算上与光线投射算法一样简单。它的优雅让我大吃一惊
我的代码
这是我最近用Java写的一些代码,它处理由线段和圆弧组成的路径。(也是圆,但它们本身就是完整的路径,所以这是一种退化的情况。
编辑:根据请求,添加一些使用此功能的示例代码。