示例#1
0
 public function distance(Image_3D_Line $line)
 {
     // Calculate parameters for plane
     $normale = $this->getNormale();
     $A = $normale->getX();
     $B = $normale->getY();
     $C = $normale->getZ();
     $D = -($normale->getX() * $this->_points[0]->getX() + $normale->getY() * $this->_points[0]->getY() + $normale->getZ() * $this->_points[0]->getZ());
     // Calculate wheather and where line cuts the polygons plane
     $lineDirection = $line->getDirection();
     $denominator = -($A * $line->getX() + $B * $line->getY() + $C * $line->getZ() + $D);
     $numerator = $A * $lineDirection->getX() + $B * $lineDirection->getY() + $C * $lineDirection->getZ();
     // Nu cut, when denomintor equals 0 (parallel plane)
     if ((int) ($denominator * 100000) === 0) {
         return false;
     }
     if ((int) ($numerator * 100000) === 0) {
         return false;
     }
     $t = $denominator / $numerator;
     // No cut, when $t < 0 (plane is behind the camera)
     if ($t <= 0) {
         return false;
     }
     // TODO: Perhaps add max distance check with unified normale vector
     // Calculate cutting point between line an plane
     $cuttingPoint = $line->calcPoint($t);
     // Perform fast check for point in bounding cube;
     if ($cuttingPoint->getX() < $this->_boundingRect[0] || $cuttingPoint->getY() < $this->_boundingRect[1] || $cuttingPoint->getZ() < $this->_boundingRect[2] || $cuttingPoint->getX() > $this->_boundingRect[3] || $cuttingPoint->getY() > $this->_boundingRect[4] || $cuttingPoint->getZ() > $this->_boundingRect[5]) {
         return false;
     }
     // perform exact check for point in polygon
     $lastScalar = 0;
     foreach ($this->_points as $nr => $point) {
         $nextPoint = $this->_points[($nr + 1) % count($this->_points)];
         $edge = new Image_3D_Vector($nextPoint->getX() - $point->getX(), $nextPoint->getY() - $point->getY(), $nextPoint->getZ() - $point->getZ());
         $v = new Image_3D_Vector($cuttingPoint->getX() - $point->getX(), $cuttingPoint->getY() - $point->getY(), $cuttingPoint->getZ() - $point->getZ());
         $scalar = $edge->crossProduct($v)->scalar($normale);
         if ($scalar * $lastScalar >= 0) {
             $lastScalar = $scalar;
         } else {
             return false;
         }
     }
     // Point is in polygon, return distance to polygon
     return $t;
 }