1

我正在尝试在 PHP 中创建一个算法,如果一个多边形的区域穿过另一个多边形的区域,或者它完全在里面,它应该返回 true。

Sutherland–Hodgman 算法是我正在寻找的那种算法,但我需要它在 php 中。

这是来自维基百科的伪代码:

List outputList = subjectPolygon;  

  for (Edge clipEdge in clipPolygon) do
     List inputList = outputList;
     outputList.clear();
     //
     for(int i = 0 ; i < inputList.count ; i += 1) do
        Point current_point = inputList[i];
        Point prev_point = inputList[((i % inputList.count) + inputList.count) % inputList.count];

        Point Intersecting_point = ComputeIntersection(prev_point,current_point,clipEdge)

        if (current_point inside clipEdge) then
           if (prev_point not inside clipEdge) then
              outputList.add(Intersecting_point);
           end if
           outputList.add(current_point);

        else if (prev_point inside clipEdge) then
           outputList.add(Intersecting_point);
        end if

     done
  done

我的多边形实际上是由纬度和经度坐标保存的,但我认为这不会给算法带来任何问题。

你认为我有可能做我所描述的吗?或者如果不是,请问我的逻辑错误是什么?

另一个问题是:如果我有一个多边形,其所有边界都在另一个多边形内,它永远不会越过它。那么算法在这种情况下会起作用吗?

祝你今天过得愉快 !


2019 年 3 月 4 日更新

我发现了一个非常不错的工具,名为geoPHP,它使用 GEOS 库。我已经将它安装在我的服务器上,它可以部分工作。

这是我的测试代码:

         if (geoPHP::geosInstalled()) {
            print "GEOS installed :)<hr>";
          }
          else {
            print "GEOS not installed :(<hr>";
          }

        $polygon = geoPHP::load('POLYGON((1 1,5 1,5 5,1 1))','wkt');
        $area = $polygon->getArea();
        $centroid = $polygon->getCentroid();
        $centX = $centroid->getX();
        $centY = $centroid->getY();
        print "Polygon 1: <br>";
        print "Area: ".$area." <br> Center :  X=".$centX." and Y=".$centY;

        $polygon2 = geoPHP::load('POLYGON((2 2,2 3,3 3,3 2,2 2))','wkt');
        $area = $polygon2->getArea();
        $centroid = $polygon2->getCentroid();
        $centX = $centroid->getX();
        $centY = $centroid->getY();
        print "<hr>Polygon 2: <br>";
        print "Area: ".$area." <br> Center :  X=".$centX." and Y=".$centY;

        print "<hr>";

        if($polygon2->crosses($polygon)){
            print "IT CROSSES";
        }else{
            print "IT DOESN'T CROSSES";
        }

它应该交叉,但是$polygon2->crosses($polygon)方法返回false,我不明白为什么......

这是我得到的结果:

此代码的结果

我希望我做得很好,我想了解为什么我不能使用我在本文档中找到的“十字架”方法

4

1 回答 1

1

终于找到了解决我所有问题的方法!

  1. https://geophp.net/并下载源代码
  2. 按照此链接https://packages.debian.org/stretch-backports/amd64/php-geos/download安装包 php-geos
  3. 启用 php-geos 包 (geos.ini)
  4. “交叉”方法不是我要找的方法!好的是“相交

正确的代码是:

         include("geophp/geoPHP.inc");

         if (geoPHP::geosInstalled()) {
           print "GEOS installed :)<hr>";
         }
         else {
           print "GEOS not installed :(<hr>";
         }

        $polygon = geoPHP::load('POLYGON((1 1, 4 1, 4 4, 1 4, 1 1))','wkt');
        $area = $polygon->getArea();
        $centroid = $polygon->getCentroid();
        $centX = $centroid->getX();
        $centY = $centroid->getY();
        print "Polygon 1: <br>";
        print "Area: ".$area." <br> Center :  X=".$centX." and Y=".$centY;

        $polygon2 = geoPHP::load('POLYGON((2 2, 3 2, 3 3, 2 3, 2 2))','wkt');
        $area = $polygon2->getArea();
        $centroid = $polygon2->getCentroid();
        $centX = $centroid->getX();
        $centY = $centroid->getY();
        print "<hr>Polygon 2: <br>";
        print "Area: ".$area." <br> Center :  X=".$centX." and Y=".$centY;

        print "<hr>";

        if($polygon2->intersects($polygon)){
            print "OK";
        }else{
            print "NOT OK";
        }
于 2019-04-03T09:38:42.470 回答