function polygon_finder_recursive(Graph $graph, $currentPolygon, $currentVertex, $lastVertex) { // Interdiction path table // Struct : array[ pointGuid1 ][ pointGuid2 ] static $pathTable = array(); $polygons = array(); $return = false; $vertices = $graph->vertices; $edges = $graph->edges; if (is_null($lastVertex) || !isset($pathTable[$lastVertex->guid][$currentVertex->guid])) { // The path loops = area found if (in_array($currentVertex, $currentPolygon)) { // Working backward to find the closure point, exclude non-area included vertices $polygon = new Polygon(); do { $newPoint = array_pop($currentPolygon); $polygon->addPoint($newPoint); } while ($currentVertex != $newPoint); $currentPolygon = $polygon; // If the polygon area doesn't include the central point if ($polygon->includes(reset($vertices)) !== 1) { // Update the interdiction table $j = count($currentPolygon) - 1; for ($k = 0; $k < count($currentPolygon); $k++) { //$pathTable[ $currentPolygon[ $j ]->guid ][ $currentPolygon[ $k ]->guid ] = true; $pathTable[$currentPolygon[$k]->guid][$currentPolygon[$j]->guid] = true; $j++; if ($j == count($currentPolygon)) { $j = 0; } } $return = $currentPolygon; } } else { $currentPolygon[] = $currentVertex; if (is_null($lastVertex)) { // First point : we search every line from the point foreach (array_keys($edges[$currentVertex->guid]) as $guid) { $polygon = polygon_finder_recursive($graph, $currentPolygon, $vertices[$guid], $currentVertex); if ($polygon !== false) { $polygonList[] = $polygon; } $return = $polygonList; } } else { // Existing line : we follow the first available path with the smallest angle $angleList = array(); foreach (array_keys($edges[$currentVertex->guid]) as $guid) { // Stop condition : already passed through here in this direction if ($lastVertex->guid != $guid && !isset($pathTable[$currentVertex->guid][$vertices[$guid]->guid])) { $angleList[$guid] = Point::anglePolar($lastVertex, $currentVertex, $vertices[$guid]); } } asort($angleList); list($guid, $angle) = each($angleList); if (!is_null($guid)) { $return = polygon_finder_recursive($graph, $currentPolygon, $vertices[$guid], $currentVertex); } } } } return $return; }