【问题标题】:How to find if a point is inside of a polygon using Racket如何使用球拍查找点是否在多边形内
【发布时间】:2014-01-12 06:28:30
【问题描述】:

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

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

如果一个点在该多边形内,谁能帮我找出解决方法,或者解决问题的更好方法?

【问题讨论】:

  • 是凸多边形还是凹多边形?还是只是一个简单的矩形?
  • 都是凹多边形,抱歉我没想到。

标签: racket polygon


【解决方案1】:

您需要从收集多边形的片段开始。 对于点 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有完整的解决方案

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/

【讨论】:

    【解决方案2】:

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

    看下图:

    我们怎么知道C 在边缘之​​间OAOBD 在外面?很简单:我们比较一些角度:如果OCOA 之间的角度小于OBOA 之间的角度,那么C 显然比OB 更接近OA

    现在,我们如何只知道一些向量来获得角度?我们可以使用单调的余弦:它随着参数的增加而减少。因此,OCOA 之间夹角的余弦大于 OBOA 夹角的余弦,后者又大于 ODOA 夹角的余弦.

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

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

    2D 中的点积很简单:

    dotproduct(OC; OA) = (C.x - O.x) * (A.x - O.x) + (C.x - O.x) * (A.x - O.x)
    

    结合以上所有内容,您应该有一个简单的测试来检查您的点是否与CD 处于相同的情况:是否比前一个边缘更接近一个边缘。

    现在,您必须对多边形的每条边重复此操作,然后就完成了。如果测试是谓词,您可以使用 fold 执行此操作。

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

    第二个说明:在图中,如果DC 或两者都在OA 行下方会发生什么?考虑一下并检查是否意味着对上述fold 方法进行更多更改。

    最后一点:假设任务已经结束,几周后我将发布完整的代码。另外,到时候我会回答上面注释中的问题。

    【讨论】:

    • 这太好了,非常感谢。假期结束后我会仔细研究一下,但我了解测试并有计划。作为参考,这里是邻里地图的图像,向您展示我将使用的形状类型。 imgur.com/eZRa1fD
    • 您需要将 poligons 拆分为凸面的,才能使其正常工作。您可以使用三角形网格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-26
    • 2022-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多