Exemplo n.º 1
0
 protected function _raytrace()
 {
     // Create basic ray ... modify direction later
     $ray = new Image_3D_Line($this->_camera->getX(), $this->_camera->getY(), $this->_camera->getZ(), new Image_3D_Vector(0, 0, 1));
     // Colorarray for resulting image
     $canvas = array();
     // Iterate over viewplane
     for ($x = -$this->_size[0]; $x < $this->_size[0]; ++$x) {
         for ($y = -$this->_size[1]; $y < $this->_size[1]; ++$y) {
             $canvas[$x + $this->_size[0]][$y + $this->_size[1]] = array();
             // Iterate over rays for one pixel
             $inPixelRayDiff = 1 / ($this->_rays + 1);
             for ($i = 0; $i < $this->_rays; ++$i) {
                 for ($j = 0; $j < $this->_rays; ++$j) {
                     // Modify ray
                     $ray->setDirection(new Image_3D_Vector($x + $i * $inPixelRayDiff - $this->_camera->getX(), $y + $j * $inPixelRayDiff - $this->_camera->getY(), -$this->_camera->getZ()));
                     // Get color for ray
                     $color = $this->_sendRay($ray, $this->_depth);
                     if ($color !== false) {
                         $canvas[$x + $this->_size[0]][$y + $this->_size[1]][] = $color;
                     } else {
                         $canvas[$x + $this->_size[0]][$y + $this->_size[1]][] = $this->_background;
                     }
                 }
             }
         }
     }
     return $canvas;
 }
Exemplo n.º 2
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;
 }