Java:查找凸多边形的最外侧顶点

时间:2012-04-01 21:04:23

标签: java geometry 2d trigonometry convex-hull

原帖:

我正在尝试找到凸多边形的最外侧顶点(与多边形外的点 P 有关)。现在,我只关心矩形(但是,我想要一个适用于任何凸多边形的算法)。

Point Demonstration

我的计划是从外部点 P 到中心点 C 构建一条线。从参考线开始,我将构建从 P 点到 1 2 点的线3 4 。由于 2 4 点将具有参考线中最大(最正)和最小(最负)的角度,因此它们将是标识为最外层顶点

这是这项工作的最佳算法吗?如何从参考角度(最好用Java)计算角度?


澄清更新:

enter image description here

我画了一行(参考线为红色)。如您所见,从 P 2 的行在参考线的一侧创建了最大角度,而来自<的行strong> P 到 4 创建另一侧的最大角度。因此,这些是最外层顶点

3 个答案:

答案 0 :(得分:2)

这几乎是convex hull问题。您将在多边形周围寻找一组顶点(x 1 ,x 2 )。将应用的方法称为“快速船体”,类似于快速排序(因为我们每次单步时都会划分我们的点区域)。这也是一个安全的假设, P 可以用作任意起点和平行终点之间的中点,因此你可以在 P 周围得到一个凸包。

需要一段时间来制作一些可靠的Java来捅(从我的偶然事件中),但我认为维基百科条目将为你提供一个很好的起点。

答案 1 :(得分:0)

使用三角法非常慢。你应该使用另一个角度比较。

对于两个平面向量之间的角度:

cos(OA,OB)=(OA x * OB x + OA y * OB y )/ sqrt((OA x 2 + OA y 2 )*(OB x 2 + OB y 2 ))

我认为,你可以比较具有余弦的角度。

答案 2 :(得分:0)

我解决了以下问题:

            // 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;
                }
            }