【问题标题】:Point inside a 2D Polygon点在 2D 多边形内
【发布时间】:2017-08-14 00:30:58
【问题描述】:

以下一段 java 代码是确定二维点是否在多边形内的解决方案(取自 here)。我认为这段代码有一些问题。例如对于这个多边形:

Point[] polygon = new Point[5];
polygon[0] = new Point(30,20);
polygon[1] = new Point(80,10);
polygon[2] = new Point(75,100);
polygon[3] = new Point(40,100);
polygon[4] = new Point(55,65);

它为 (76,82) 返回 true(内部),但该点位于边缘(代码为边缘上的另一个点正确返回 false:(45,17))。 它还为 (45,90) 返回 false(不在内部),但它在多边形内部。有什么问题?

public boolean IsPointInPolygon(Point p, Point[] polygon)
{
    double minX = polygon[0].x;
    double maxX = polygon[0].x;
    double minY = polygon[0].y;
    double maxY = polygon[0].y;
    for ( int i = 1 ; i < polygon.length; i++ )
    {
        Point q = polygon[i];
        minX = Math.min(q.x, minX);
        maxX = Math.max(q.x, maxX);
        minY = Math.min(q.y, minY);
        maxY = Math.max(q.y, maxY);
    }

    if ( p.x <= minX || p.x >= maxX || p.y <= minY || p.y >= maxY )
    {
        return false;
    }

    boolean inside = false;
    int j = polygon.length - 1;
    for (int i = 0 ;i < polygon.length ; j = i++)
    {
        if (( polygon[i].y > p.y ) != ( polygon[j].y > p.y) &&
                p.x <= (polygon[j].x - polygon[i].x ) * ( p.y - polygon[i].y ) / ( polygon[j].y - polygon[i].y ) + polygon[i].x)
        {
            inside = !inside;
        }
    }
    return inside;
}

我想我应该把我的代码改成下面,但我不确定!

float tempX = ((float)((polygon[i].x - polygon[j].x) * (p.y - polygon[i].y)) / (polygon[i].y - polygon[j].y)) + polygon[i].x;
if (p.x < tempX) {
    inside = !inside;
}
else if (p.x == tempX) {
    return false;
}

【问题讨论】:

  • 我建议您使用调试器并逐行执行,直到您发现没有执行您认为应该执行的操作。
  • (1) 链接页面的作者写道,对于边缘点,结果为真或假。因此,您的前两个测试用例的行为是可以预料的。 (2) 您使用的是p.x &lt;= ...,而原始代码使用的是&lt;。 (3) 您是否尝试在数组末尾重复第一个点?作者写道,在您的情况下它是可选的,但我仍然会尝试。
  • (2) 我正在使用 p.x
  • 我想我应该把我的代码改成下面,但我不确定! float tempX = ((float)((polygon[i].x - polygon[j].x) * (p.y - polygon[i].y)) / (polygon[i].y - polygon[j].y )) + 多边形[i].x; if (p.x

标签: java point-in-polygon


【解决方案1】:

这个算法

if ( p.x <= minX || p.x >= maxX || p.y <= minY || p.y >= maxY )
{
        return false;
}

错了。它只检查该点是否在以minX, maxX, minY, maxY 为边界的矩形内 如果不使用所有多边形顶点,则无法测试点是否在多边形内。

使用java.awt.Polygon

public boolean isPointInPolygon(Point p, Point[] points)
    {

        Polygon polygon = new Polygon();//java.awt.Polygon

        for(Point point : points) {

            polygon.addPoint(point.x, point.y);
        }

        return polygon.contains(p);
    }

测试它

    Point[] points = new Point[5];
    points[0] = new Point(30,20);
    points[1] = new Point(80,10);
    points[2] = new Point(75,100);
    points[3] = new Point(40,100);
    points[4] = new Point(55,65);

    System.out.println(isPointInPolygon(new Point(76,82), points) );

打印出错误。

【讨论】:

  • 但是您可以快速确定一个点在多边形内。例如,如果多边形的所有顶点的x坐标>= 0,并且测试点的x坐标为-2,则可以确定该点位于多边形之外。
  • 此代码对边缘上的点返回 true,但我想返回 false。
  • 嗨,c0der,如果坐标是负数怎么办?如果我有(-119.2342399, +35.23423234) 作为多边形的坐标。 points[0] = new Point(30,20); 似乎不接受负值。
  • 你能建议如何找到吗?
  • @Michael 抱歉,如何找到? java.awt.Point 接受负值,但只接受整数:points[0] = new Point(-119, +35);。如果您需要double 值的解决方案,请发布新问题,并在此处给我留言。
猜你喜欢
  • 2014-12-20
  • 1970-01-01
  • 2016-11-02
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-31
  • 2014-06-16
相关资源
最近更新 更多