/** * @param Node $node * @return ListNode */ protected function convertNode(Node $node) { if ($node instanceof ListNode) { return $node; } $listNode = new ListNode($node->getId(), $node->getX(), $node->getY(), 0); $listNode->setData($node->getData()); return $listNode; }
/** * @param Node $node * @param bool $diagonal * @return Node[] */ public function getNeighbors(Node $node, $diagonal = false) { $result = array(); $x = $node->getX(); $y = $node->getY(); $neighbourLocations = [[$y - 1, $x], [$y + 1, $x], [$y, $x - 1], [$y, $x + 1]]; if ($diagonal) { $neighbourLocations[] = [$y - 1, $x - 1]; $neighbourLocations[] = [$y + 1, $x - 1]; $neighbourLocations[] = [$y - 1, $x + 1]; $neighbourLocations[] = [$y + 1, $x + 1]; } foreach ($neighbourLocations as $location) { list($y, $x) = $location; $node = $this->getPoint($y, $x); if ($node) { $result[] = $node; } } return $result; }
/** * @param Node $node1 * @param Node $node2 * @return float */ public static function getLinearDistance(Node $node1, Node $node2) { $dist_x = abs($node1->getX() - $node2->getX()); $dist_y = abs($node1->getY() - $node2->getY()); return hypot($dist_x, $dist_y); }
function addControlPoint(Node &$nodeA, Node &$nodeB, Node &$nodeC) { $midPointBC = array('x' => ($nodeB->getX() + $nodeC->getX()) / 2, 'y' => ($nodeB->getY() + $nodeC->getY()) / 2); $cPointX = ($midPointBC['x'] + $nodeA->getX()) / 2; $cPointY = ($midPointBC['y'] + $nodeA->getY()) / 2; $CPname = $this->addNode($cPointX, $cPointY); $this->nodes[$CPname]->addChild($nodeB); $this->nodes[$CPname]->addChild($nodeC); $this->nodes[$CPname]->setType(Node::N_TYPE_CTRL_POINT); return $CPname; }
public function getWalkableNeighbors(Node $node) { if (!$node->isWalkable()) { return array(); } $deltas = array(array(-1, -1), array(-1, +0), array(-1, +1), array(+0, -1), array(+0, +1), array(+1, -1), array(+1, +0), array(+1, +1)); $neighbors = array(); foreach ($deltas as $delta) { $x = $node->getX() + $delta[0]; $y = $node->getY() + $delta[1]; if ($this->isWalkableAt($x, $y)) { $neighbors[] = $this->getNodeAt($x, $y); } } return $neighbors; }
function connect(Node &$nodeA, Node &$nodeB) { // $orphan = $nodeB->findClosestOrphan($this->nodes); $orphan = $nodeB->findClosest(); if (!$orphan) { return; } $nodeC =& $this->nodes[$nodeB->findClosest()]; $dAC = $nodeA->getRelation($nodeC->name); $dBC = $nodeB->getRelation($nodeC->name); if ($dBC <= $dAC) { $midPointBC = array('x' => ($nodeB->getX() + $nodeC->getX()) / 2, 'y' => ($nodeB->getY() + $nodeC->getY()) / 2); $cPointX = ($midPointBC['x'] + $nodeA->getX()) / 2; $cPointY = ($midPointBC['y'] + $nodeA->getY()) / 2; $CPname = $this->addNode($cPointX, $cPointY); $this->nodes[$CPname]->addChild($nodeB); $this->nodes[$CPname]->addChild($nodeC); $this->nodes[$CPname]->setType(Node::N_TYPE_CTRL_POINT); $this->sourceNode->addChild($this->nodes[$CPname]); } if ($this->hasOrphans()) { $nextNode = $nodeB->findClosestOrphan($this->nodes); $nextNode = $this->nodes[$nextNode]; if ($nextNode->getRelation($nodeB->name) <= $this->sourceNode->getRelation($nextNode->name) && $nodeB->getChildrenCount() < 2) { if ($nodeC->getRelation($nextNode->name) < $nodeB->getRelation($nextNode->name)) { $this->nodes[$nodeC->name]->addChild($nextNode); } else { $this->nodes[$nodeB->name]->addChild($nextNode); } } } // if($this->hasOrphans()){ // $this->connect($this->nodes[$nodeB->name], $this->nodes[$nodeC->name]); // } // debug_arr($this->sourceNode->getChildren()); $this->nodes[$nodeA->name] = $nodeA; }
function addControlPoint(Node $nodeA, Node $nodeB) { $cPointX = ($nodeA->getX() + $nodeB->getX()) / 2; $cPointY = ($nodeA->getY() + $nodeB->getY()) / 2; $CPname = $this->addNode($cPointX, $cPointY); // remove A from dataset $this->removeNode($nodeA->name); // remove B from dataset $this->removeNode($nodeB->name); // make A/B children of new control point $this->nodes[$CPname]->addChild($nodeA); $this->nodes[$CPname]->addChild($nodeB); // set new node type as control point $this->nodes[$CPname]->setType(Node::N_TYPE_CTRL_POINT); $this->rebuildRelationAll(); $this->connections[$nodeA->name] = $CPname; $this->connections[$nodeB->name] = $CPname; $this->addToBin($this->nodes[$CPname]); return $CPname; }