/** * Return the inward-facing normal of the great circle passing through the * edge from vertex k to vertex k+1 (mod 4). The normals returned by * GetEdgeRaw are not necessarily unit length. * * If this is not a leaf cell, set children[0..3] to the four children of * this cell (in traversal order) and return true. Otherwise returns false. * This method is equivalent to the following: * * for (pos=0, id=child_begin(); id != child_end(); id = id.next(), ++pos) * children[i] = S2Cell(id); * * except that it is more than two times faster. * @param S2Cell[] $children */ public function subdivide(&$children) { // This function is equivalent to just iterating over the child cell ids // and calling the S2Cell constructor, but it is about 2.5 times faster. if ($this->cellId->isLeaf()) { return false; } // Compute the cell midpoint in uv-space. $uvMid = $this->getCenterUV(); // Create four children with the appropriate bounds. /** @var S2CellId $id */ $id = $this->cellId->childBegin(); for ($pos = 0; $pos < 4; ++$pos, $id = $id->next()) { $child =& $children[$pos]; $child->face = $this->face; $child->level = $this->level + 1; $new_o = S2::posToOrientation($pos); $child->orientation = $this->orientation ^ $new_o; // echo "this-ori:" . $this->orientation . " new_o:" . $new_o . " res:" . $child->orientation . "\n"; $child->cellId = $id; $ij = S2::posToIJ($this->orientation, $pos); for ($d = 0; $d < 2; ++$d) { // The dimension 0 index (i/u) is in bit 1 of ij. $m = 1 - ($ij >> 1 - $d & 1); $child->uv[$d][$m] = $uvMid->get($d); $child->uv[$d][1 - $m] = $this->uv[$d][1 - $m]; } } return true; }