Проверьте, находится ли Polygon внутри другого Polygon в PHP - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь создать алгоритм в PHP, который должен возвращать true, если область многоугольника пересекает область другого, или если он полностью внутри.

Алгоритм Сазерленда-Ходжмана - это тот алгоритм, который я ищу, но он мне понадобится в 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

Мои полигоны фактически сохраняются по координатам широты и долготы, но я не думаю, что это приведет к какой-либо проблеме для алгоритма.

Вы думаете, что я могу сделать то, что я описал? Или, если это не так, в чем моя логическая ошибка, пожалуйста?

Другой вопрос: если у меня есть многоугольник со всеми границами внутри другого многоугольника, он никогда не пересечет его. Так будет ли работать алгоритм в этом случае?

Хорошего дня!


ОБНОВЛЕНИЕ 03/04/2019

Я нашел довольно хороший инструмент с именем 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, я не могу понять, почему ...

Вот результат, который я получаю:

Result of this code

Надеюсь, у меня все хорошо, я хотел бы понять, почему я не могу использовать метод "крестов", который я нахожу в этой документации

1 Ответ

1 голос
/ 03 апреля 2019

Наконец-то узнал, как решить все мои проблемы!

  1. Переход к https://geophp.net/ и загрузка источников
  2. Установка пакета php-geos по этой ссылке https://packages.debian.org/stretch-backports/amd64/php-geos/download
  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";
        }
...