/** return a vector orthogonal to this one */
 public function ortho()
 {
     $k = $this->largestAbsComponent();
     if ($k == 1) {
         $temp = new S2Point(1, 0, 0);
     } else {
         if ($k == 2) {
             $temp = new S2Point(0, 1, 0);
         } else {
             $temp = new S2Point(0, 0, 1);
         }
     }
     return S2Point::normalize($this->crossProd($this, $temp));
 }
Ejemplo n.º 2
0
 public static function toPoint()
 {
     return S2Point::normalize(self::toPointRaw());
 }
 /**
  * Return the average area for cells at the given level.
  *#/
  * public static double averageArea(int level) {
  * return S2Projections.AVG_AREA.getValue(level);
  * }
  *
  * /**
  * Return the average area of cells at this level. This is accurate to within
  * a factor of 1.7 (for S2_QUADRATIC_PROJECTION) and is extremely cheap to
  * compute.
  *#/
  * public double averageArea() {
  * return averageArea(level);
  * }
  *
  * /**
  * Return the approximate area of this cell. This method is accurate to within
  * 3% percent for all cell sizes and accurate to within 0.1% for cells at
  * level 5 or higher (i.e. 300km square or smaller). It is moderately cheap to
  * compute.
  *#/
  * public double approxArea() {
  *
  * // All cells at the first two levels have the same area.
  * if (level < 2) {
  * return averageArea(level);
  * }
  *
  * // First, compute the approximate area of the cell when projected
  * // perpendicular to its normal. The cross product of its diagonals gives
  * // the normal, and the length of the normal is twice the projected area.
  * double flatArea = 0.5 * S2Point.crossProd(
  * S2Point.sub(getVertex(2), getVertex(0)), S2Point.sub(getVertex(3), getVertex(1))).norm();
  *
  * // Now, compensate for the curvature of the cell surface by pretending
  * // that the cell is shaped like a spherical cap. The ratio of the
  * // area of a spherical cap to the area of its projected disc turns out
  * // to be 2 / (1 + sqrt(1 - r*r)) where "r" is the radius of the disc.
  * // For example, when r=0 the ratio is 1, and when r=1 the ratio is 2.
  * // Here we set Pi*r*r == flat_area to find the equivalent disc.
  * return flatArea * 2 / (1 + Math.sqrt(1 - Math.min(S2.M_1_PI * flatArea, 1.0)));
  * }
  *
  * /**
  * Return the area of this cell as accurately as possible. This method is more
  * expensive but it is accurate to 6 digits of precision even for leaf cells
  * (whose area is approximately 1e-18).
  *#/
  * public double exactArea() {
  * S2Point v0 = getVertex(0);
  * S2Point v1 = getVertex(1);
  * S2Point v2 = getVertex(2);
  * S2Point v3 = getVertex(3);
  * return S2.area(v0, v1, v2) + S2.area(v0, v2, v3);
  * }
  *
  * // //////////////////////////////////////////////////////////////////////
  * // S2Region interface (see {@code S2Region} for details):
  *
  * @Override
  * public S2Region clone() {
  * S2Cell clone = new S2Cell();
  * clone.face = this.face;
  * clone.level = this.level;
  * clone.orientation = this.orientation;
  * clone.uv = this.uv.clone();
  *
  * return clone;
  * }
  */
 public function getCapBound()
 {
     // Use the cell center in (u,v)-space as the cap axis. This vector is
     // very close to GetCenter() and faster to compute. Neither one of these
     // vectors yields the bounding cap with minimal surface area, but they
     // are both pretty close.
     //
     // It's possible to show that the two vertices that are furthest from
     // the (u,v)-origin never determine the maximum cap size (this is a
     // possible future optimization).
     $u = 0.5 * ($this->uv[0][0] + $this->uv[0][1]);
     $v = 0.5 * ($this->uv[1][0] + $this->uv[1][1]);
     $cap = S2Cap::fromAxisHeight(S2Point::normalize(S2Projections::faceUvToXyz($this->face, $u, $v)), 0);
     for ($k = 0; $k < 4; ++$k) {
         $cap = $cap->addPoint($this->getVertex($k));
     }
     return $cap;
 }