我可能需要对多边形内的大量点进行此计算(例如50-200个点)。
该算法的每个步骤都是线性时间(O(n))。
以下是每个步骤的基本公式:
计算与多边形每条边相切的直线上最近点。
p1 = {x1,y1}
。p2 = {x2,y2}
。p3 = {x3,y3}
。u
是需要查找沿由 p1 和 p2 形成的直线的点的距离的百分比,以便使 p1+u(p2-p1)
= 最靠近 p3 的点(连接此点和 p3 的线段也恰好垂直于通过 p1 和 p2 的线)。u = ((x3 - x1)(x2 - x1)+(y3 - y1)(y2 - y1)) / ((x2 - x1)^2 + (y2 - y1)^2)
pu = {xu,yu}
xu = x1 + u (x2 - x1)
yu = y1 + u (y2- y1)
pu ={xu,yu}
计算每条线段(多边形的边缘)到待求点的最近点。
当0<=u<=1
时,点pu
只是线段上最近的点。否则,线段的适当端点是离待求点最近的点。因此,针对上一步中计算出的每个pu、p1、p2 和 u
,执行以下操作:
让pc = {xc,yc}
表示多边形边缘的线段上距离待求点最近的点。IF u<0 THEN pc = p1
ELSE IF u>1 THEN pc = p2
ELSE pc = pu
计算每个线段上最近点到待求点的距离。
p3
与pc
之间的距离= `sqrt((x3-xc)^2+(y3-yc)^2)寻找最小距离。 相应的多边形边缘就是答案。
以下是一个图示,以帮助您了解本帖中的点和术语:
....
# ELSE IF u>0 THEN pc = p2
有一个笔误了... 应该是u>1吧? - Dr. belisarius正确答案取决于问题的整体结构:当考虑到多个查询时会发生什么?我假设每个查询将涉及不同的点。但是这个多边形呢?你是否期望收到多个关于同一多边形的查询?还是每次多边形都不同?
如果每个查询都应用于不同的、不可预测的多边形,那么你唯一的解决方案就是基本上要检查所有多边形边缘,并对每个边缘进行点到线段距离测试。它可以通过各种[启发式]方式进行优化(提前丢弃无用的测试),但在最坏的情况下,没有绕过全面测试的方法。
然而,如果你期望在问题的多边形方面有某种可预测性和稳定性(足够多的点对同一多边形或一组固定多边形的查询),那么情况就会发生戏剧性变化。在这种情况下,最好的方法是预先构建多边形内的基于边缘的Voronoi图。然后,你可以解决点位置问题(已知有效算法)以确定查询点落入哪个Voronoi区域。这将立即告诉你最接近的边缘是哪一个。
当你需要处理许多对同一多边形的点查询时,后者效率无与伦比,但需要相当大的努力来实现。因此,这完全取决于您需要什么样的解决方案。
P.S. 我看到你在问题中说你要为单个多边形运行大量点集。这立即使基于 Voronoi 图的解决方案成为首选。算法的额外细节可能取决于那个大点集是完全预先知道的还是以不可预测的方式逐点到达。