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; }
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; }