如何使用Racket查找点是否在多边形内部

时间:2013-12-24 01:32:19

标签: racket polygon

我正在开发一个项目,给定一个特定的纬度和经度坐标,输出该点所在的邻域。我有一个纬度和经度坐标,构成一个城市内几个街区的边界。我必须从文件中读取邻域数据,并从文件中读取测试点。我正在使用Racket编程语言。

到目前为止,我已经能够读取文件并为每个社区创建一个点列表,现在我被卡住了。我想为每个邻域创建一个多边形,然后有一个方法检查一个点是否位于该多边形内。但是,我无法弄清楚如何使用Racket来做到这一点。

任何人都可以帮我找到如果一个点在该多边形内的解决方法,或者可能是解决问题的更好方法吗?

2 个答案:

答案 0 :(得分:8)

我暂时不会发布任何代码,因为我不想解决作业/作业。但是,我会发一些提示。

请看下面的图片:

Some vectors

我们怎么知道C位于OAOB之间,而D位于外边?很简单:我们比较一些角度:如果OCOA之间的角度小于OBOA之间的角度,那么C显然更接近{{1} } {而不是OA

现在,我们如何才知道角度只知道一些向量?我们可以使用单调的余弦:它随着参数的增加而减少。因此,OBOC之间的角度的余弦大于OAOB之间的角度的余弦,而角度的余弦又大于角度的余弦。在OAOD之间。

下一步是弄清楚如何计算余弦。矢量点积有助于:它的值是角度的余弦值大于操作数长度的乘积。那就是:

OA

2D中的dotproduct很简单:

cos(OC; OA) = dotproduct(OC; OA) / (length(OA) * length(OC))

结合上述所有内容,您应该进行一项简单的测试,以检查您的观点是否与dotproduct(OC; OA) = (C.x - O.x) * (A.x - O.x) + (C.x - O.x) * (A.x - O.x) C的情况相同:是否比上一个边缘更靠近一个边缘。< / p>

现在,您必须为多边形的每个边缘重复此操作,并且您已完成。如果测试是谓词,则可以使用D执行此操作。

注意:这仅适用于多边形为凸面的情况。对于凹面多边形,您需要添加更多测试。

第二个注释:在图中,如果foldD或两者都低于C行,会发生什么?考虑一下,检查它是否意味着对上述OA方法的更多更改。

最后一点:几周后,我会发布一个完整的代码,假设作业结束了。此外,那时我会在上面的说明中回答这个问题。

答案 1 :(得分:0)

您需要先收集多边形的各段。 对于点P,您需要确定从点P开始的水平射线是否与边(段)相交。 如果计算点的水平射线相交的段数,则奇数将在内部,偶数将在外部。

  (define (point-in-polygon? point polygon)
    (odd? 
     (for/fold ([c 0]) ([seg polygon])
       (+ c (if (ray-cross-seg? point seg) 1 0))))))

我在https://github.com/StevenACoffman/lat-long-kata-racket中有完整的解决方案

https://rosettacode.org/wiki/Ray-casting_algorithm#Racket和35种其他编程语言中的替代球拍中的光线投射算法。

提供了更详细的演练:https://www.geeksforgeeks.org/how-to-check-if-a-given-point-lies-inside-a-polygon/