private static function removeMinimalTrrianglePoint(&$points, &$minimalAreaKey, &$listOfAreas) { //Recalculate new left triangle if ($minimalAreaKey > 1) { $leftPointKey = $minimalAreaKey - 1; $listOfAreas[$leftPointKey] = PointsService::getAreaTriangle($points[$leftPointKey - 1], $points[$leftPointKey], $points[$leftPointKey + 1]); } //Recalculate new right triangle if ($minimalAreaKey < count($minimalAreaKey) - 2) { $rightPointKey = $minimalAreaKey - 1; $listOfAreas[$rightPointKey] = PointsService::getAreaTriangle($points[$rightPointKey - 1], $points[$rightPointKey], $points[$rightPointKey + 1]); } //Remove old point and their area of trangle unset($points[$minimalAreaKey]); unset($listOfAreas[$minimalAreaKey]); //flush keys // TODO: need replace it to more faster logic $points = array_values($points); $listOfAreas = array_values($listOfAreas); // print_r($listOfAreas); $minimalArea = $listOfAreas[1]; $minimalAreaKey = 1; for ($i = 2, $size = count($listOfAreas); $i < $size; $i++) { if ($minimalArea > $listOfAreas[$i]) { $minimalArea = $listOfAreas[$i]; $minimalAreaKey = $i; } } }
public static function runWithoutRecursion($points, $epsilonSquare) { // $watchdog = 0; $stack = [[0, count($points) - 1]]; while (!empty($stack)) { //Just for testing mode // if(++$watchdog>10000) // { // break; // } $limits = array_pop($stack); //TODO: Heare heed check variant if we have 3 points and current //length more than epsilon not need add new diapasons to stack if ($limits[1] - $limits[0] < 2) { continue; } $keyOfMaxEl = null; $maxLength = 0; for ($i = $limits[0] + 1; $i < $limits[1]; $i++) { // TODO: Need remove repeating calculation on base line point coordinates //possible bad variand becouse same points will happen not very often but comparation happen for all limits // if($points[$limits[0]] === $points[$limits[1]]) // { // //same start and end point can use just distance between 2 points // $curentLength = PointsService::getDistance2Points($points[$i], $points[$limits[0]]); // } // else // { $curentLength = PointsService::minimalLengthToLine($points[$i], $points[$limits[0]], $points[$limits[1]]); // } if ($curentLength > $maxLength) { $maxLength = $curentLength; $keyOfMaxEl = $i; } } if ($keyOfMaxEl !== null && $maxLength > $epsilonSquare) { // TODO: Need experementis 2 [] will work fater than array_push // array_push($stack, [$limits[0], $keyOfMaxEl], [$keyOfMaxEl, $limits[1]]); $stack[] = [$limits[0], $keyOfMaxEl]; $stack[] = [$keyOfMaxEl, $limits[1]]; } else { //TODO: Need replace to unset It will work ~10% faster. //Maybe not need becouse it will be lot operations exept one function call array_splice($points, $limits[0] + 1, $limits[1] - $limits[0] - 1, 0); } } $result = []; foreach ($points as $point) { if ($point !== 0) { $result[] = $point; } } return $result; }