Racket 如何使用球拍确定点是否在多边形内

Racket 如何使用球拍确定点是否在多边形内,racket,polygon,Racket,Polygon,我正在做一个项目,给定一个特定的纬度和经度坐标,输出点所在的邻域。我有纬度和经度坐标,它们构成了一个城市内几个街区的边界。我必须从文件中读取邻域数据,还必须从文件中读取测试点。我正在使用Racket编程语言 到目前为止,我已经能够阅读文件,并为每个社区创建一个点列表,现在我被卡住了。我想为每个邻域创建一个多边形,然后使用一种方法检查点是否位于该多边形内。然而,我不知道如何用球拍做到这一点 有人能帮我找出如何解决一个点是否在多边形内,或者是解决这个问题的更好方法吗?我现在不发布任何代码,因为我不想

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

到目前为止,我已经能够阅读文件,并为每个社区创建一个点列表,现在我被卡住了。我想为每个邻域创建一个多边形,然后使用一种方法检查点是否位于该多边形内。然而,我不知道如何用球拍做到这一点


有人能帮我找出如何解决一个点是否在多边形内,或者是解决这个问题的更好方法吗?

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

请看下图:

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

现在,我们如何得到只知道一些向量的角度?我们可以使用单调的余弦:它随着变元的增加而减小。因此,
OC
OA
之间的夹角的余弦大于
OB
OA
之间夹角的余弦,后者又大于
OD
OA
之间夹角的余弦

下一步是找出如何计算余弦。向量点积有帮助:它的值是角度乘以操作数长度乘积的余弦。即:

cos(OC; OA) = dotproduct(OC; OA) / (length(OA) * length(OC))
2D中的dotproduct很简单:

dotproduct(OC; OA) = (C.x - O.x) * (A.x - O.x) + (C.x - O.x) * (A.x - O.x)
结合以上所有内容,您应该有一个简单的测试来检查您的点是否与
C
D
处于相同的情况:是否比前一条边更靠近一条边

现在,你必须对多边形的每一条边重复这个步骤,你就完成了。如果测试是谓词,则可以使用
折叠
来执行此操作

注意:这仅在多边形为凸多边形时有效。对于凹多边形,需要添加更多测试

第二个注释:在图中,如果
D
C
或两者都在
OA
行下方,会发生什么情况?考虑一下这一点,并检查它是否意味着对上述
折叠方法进行更多更改


最后一点:假设作业结束,几周后我会发布一个完整的代码。同时,我将回答上面注释中的问题。

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

  (define (point-in-polygon? point polygon)
    (odd? 
     (for/fold ([c 0]) ([seg polygon])
       (+ c (if (ray-cross-seg? point seg) 1 0))))))
我有一个完整的解决方案

Racket中的另一种光线投射算法与其他35种编程语言一样适用


提供了更详细的演练:

它是凸多边形还是凹多边形?或者它只是一个简单的矩形?它们都是凹多边形,对不起,我甚至没想到要提到这一点。这太棒了,非常感谢。假期过后,我会更仔细地看一看,但我了解这些测试,并有一个计划。作为参考,这里是nieghborhood地图的图像,向您展示我将使用的形状类型。你需要将多边形分割成凸多边形,这样才能工作。可以使用三角形网格。