/** * Takes all point vectors ("vertexes") of the polygon describing the face and sorts them * in clockwise order. */ public function sortVerticesClockwise() { $center = $this->calculateCenter(); for ($n = 0; $n <= count($this->vertexes) - 3; $n++) { $a = new \Math_Vector3(\Math_VectorOp::substract($this->vertexes[$n], $center)->getTuple()); $a->normalize(); $p = Plane::getInstanceByThreePositionVectors($this->vertexes[$n], $center, new \Math_Vector3(\Math_VectorOp::add($center, $this->plane->getNormalVectorNormalized())->getTuple())); $smallestAngle = -1; $smallest = -1; for ($m = $n + 1; $m <= count($this->vertexes) - 1; $m++) { if ($p->calculateSideOfPointVector($this->vertexes[$m]) !== Plane::SIDE_BACK) { $b = new \Math_Vector3(\Math_VectorOp::substract($this->vertexes[$m], $center)->getTuple()); $b->normalize(); $angle = \Math_VectorOp::dotProduct($a, $b); if ($angle > $smallestAngle) { $smallestAngle = $angle; $smallest = $m; } } } if ($smallest == -1) { throw new \RuntimeException('Error: Degenerate polygon!'); } //swap vertices $temp = $this->vertexes[$n + 1]; $this->vertexes[$n + 1] = $this->vertexes[$smallest]; $this->vertexes[$smallest] = $temp; unset($temp); } // Check if vertex order needs to be reversed for back-facing polygon $newPlane = Plane::getInstanceByThreePositionVectors($this->vertexes[0], $this->vertexes[1], $this->vertexes[2]); if (\Math_VectorOp::dotProduct($newPlane->getNormalVectorNormalized(), $this->plane->getNormalVectorNormalized()) < 0) { array_reverse($this->vertexes); } }
/** * Verify that an exception is thrown when trying to get the intersection point with two other parallel planes */ public function testIntersectionAllParalel() { $this->setExpectedException('InvalidArgumentException'); $p1 = Plane::getInstanceByThreePositionVectors($this->x1, $this->y1, $this->z1); $add1 = new Math_Vector3(new Math_Tuple(array(0, 0, 16))); $x1p = new Math_Vector3(Math_VectorOp::add($this->x1, $add1)->getTuple()); $y1p = new Math_Vector3(Math_VectorOp::add($this->y1, $add1)->getTuple()); $z1p = new Math_Vector3(Math_VectorOp::add($this->z1, $add1)->getTuple()); $p2 = Plane::getInstanceByThreePositionVectors($x1p, $y1p, $z1p); $add2 = new Math_Vector3(new Math_Tuple(array(0, 0, 32))); $x1p2 = new Math_Vector3(Math_VectorOp::add($this->x1, $add2)->getTuple()); $y1p2 = new Math_Vector3(Math_VectorOp::add($this->y1, $add2)->getTuple()); $z1p2 = new Math_Vector3(Math_VectorOp::add($this->z1, $add2)->getTuple()); $p3 = Plane::getInstanceByThreePositionVectors($x1p2, $y1p2, $z1p2); $p1->calculateIntersectionPointWithTwoPlanes($p2, $p3); }