Java:找到凸多边形的最外层顶点
Posted
技术标签:
【中文标题】Java:找到凸多边形的最外层顶点【英文标题】:Java: Finding the Outermost Vertices of a Convex Polygon 【发布时间】:2012-04-15 15:14:20 【问题描述】:原帖:
我试图找到一个凸多边形的最外层顶点(与多边形外的一个点 P 相关)。目前,我只关心矩形(不过,我想要一种适用于任何凸多边形的算法)。
我的计划是构建一条从外部点P到中心点C的线。根据这个参考线,我将构建从点 P 到点 1、2、 的线3 和 4。由于点 2 和 4 与 参考线 之间的夹角最大(最正)和最小(最负),它们将是标识为最外层的顶点。
这是最适合这项工作的算法吗?如何从参考角度计算角度(最好在 Java 中)?
更新说明:
我已经画了线(参考线为红色)。如您所见,从 P 到 2 的线在 参考线 的一侧创建最大角度,而从 P 到 4 创建另一侧的最大角度。因此,这些是最外层的顶点。
【问题讨论】:
嗯,两点 A 和 B 之间的角度应该是 atan2(b.y,b.x) - atan2(a.y,a.x) 但简单地取最大和第二大角度可能无法解决所有情况的问题......我认为。 为什么不只考虑从 P 到 C 画线的最远点? 我想这也可以。 “我正在尝试找到凸多边形的最外层顶点(相对于多边形外部的点 P)。” - 我不明白。你能指点参考吗? 【参考方案1】:三角函数的使用非常缓慢。您应该使用另一个角度比较。
对于两个平面向量之间的夹角:
cos(OA, OB) = (OAx * OBx + OAy* OBy ) / sqrt((OAx2 + OAy2)* (OBx sub>2 + OBy2))
我认为,您可以比较具有余弦的角度。
【讨论】:
【参考方案2】:这几乎是convex hull 的问题。您将在多边形周围寻找一组顶点 (x1, x2)。将应用的方法称为“快速船体”,类似于快速排序(每次我们通过时我们都会划分我们的点区域)。 P 可以用作任意起点与其平行终点之间的中点也是一个安全的假设,因此您将在 P 周围得到一个凸包.
生成一些可靠的 Java 需要一段时间(根据我的偶然性),但我认为 Wikipedia 条目将为您提供一个很好的起点。
【讨论】:
对不起...我不认为这与凸包问题非常相似。形状的边界是已知的,我没有使用任何 Minkowski 和。此外,P 是计算的起点。我正在寻找与外部点P 相关的最外层顶点。因此,操作是迭代的,不需要逐步除法。 点 1,2,3,4 的凸包是已知的。点 P,1,2,3,4 的凸包是未知的。我认为最外面的点是 P,1,2,3,4 的凸包中与 P 相邻的两个点。注意 1 不是 P,1,2,3,4 的凸包的一部分。 啊。我现在知道了。那么凸包算法是解决这个问题的最快方法吗? @Peter:这将是一个非常快速的解决方法,是的; Quick-hull 平均可以达到 O(N*lg(N)) 的性能,最坏的情况是 O(n^2)(不太可能)。【参考方案3】:我解决的问题如下:
// code simplified for demonstration
double angleBetweenVertices;
double maxAngleBetweenVertices;
vectorA.setStartingPoint(outerPoint);
vectorA.setTerminationPoint(polygonCenter);
vectorB.setStartingPoint(outerPount);
// For each vertex, calculate the angle between the outer point, the polygon's center and the vertex
for (Point2D.Double vertex : vertices)
vectorB.setTerminationPoint(vertex);
double angleBetweenVertices =
Math.toDegrees(
Math.atan2(
(vectorA.perpDotProduct(vectorB)),
(vectorA.dotProduct(vectorB))
)
);
// Update the min and Max
if (angleBetweenVertices >= maxAngleBetweenVertices)
maxVertex = vertex;
maxAngleBetweenVertices = angleBetweenVertices;
else if (angleBetweenVertices <= minAngleBetweenVertices)
minVertex = vertex;
minAngleBetweenVertices = angleBetweenVertices;
【讨论】:
以上是关于Java:找到凸多边形的最外层顶点的主要内容,如果未能解决你的问题,请参考以下文章