我正在开发一个项目,给定一个特定的纬度和经度坐标,输出该点所在的邻域。我有一个纬度和经度坐标,构成一个城市内几个街区的边界。我必须从文件中读取邻域数据,并从文件中读取测试点。我正在使用Racket编程语言。
到目前为止,我已经能够读取文件并为每个社区创建一个点列表,现在我被卡住了。我想为每个邻域创建一个多边形,然后有一个方法检查一个点是否位于该多边形内。但是,我无法弄清楚如何使用Racket来做到这一点。
任何人都可以帮我找到如果一个点在该多边形内的解决方法,或者可能是解决问题的更好方法吗?
答案 0 :(得分:8)
我暂时不会发布任何代码,因为我不想解决作业/作业。但是,我会发一些提示。
请看下面的图片:
我们怎么知道C
位于OA
和OB
之间,而D
位于外边?很简单:我们比较一些角度:如果OC
和OA
之间的角度小于OB
和OA
之间的角度,那么C显然更接近{{1} } {而不是OA
。
现在,我们如何才知道角度只知道一些向量?我们可以使用单调的余弦:它随着参数的增加而减少。因此,OB
和OC
之间的角度的余弦大于OA
和OB
之间的角度的余弦,而角度的余弦又大于角度的余弦。在OA
和OD
之间。
下一步是弄清楚如何计算余弦。矢量点积有助于:它的值是角度的余弦值大于操作数长度的乘积。那就是:
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
执行此操作。
注意:这仅适用于多边形为凸面的情况。对于凹面多边形,您需要添加更多测试。
第二个注释:在图中,如果fold
或D
或两者都低于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/