Ejemplo n.º 1
0
bool 																 
Torus::hit(const Ray& ray, double& tmin, ShadeRec& sr) const {
	if (!bbox.hit(ray))
		return (false);
		
	double x1 = ray.o.x; double y1 = ray.o.y; double z1 = ray.o.z;
	double d1 = ray.d.x; double d2 = ray.d.y; double d3 = ray.d.z;	
	
	double coeffs[5];	// coefficient array for the quartic equation
	double roots[4];	// solution array for the quartic equation
	
	// define the coefficients of the quartic equation
	
	double sum_d_sqrd 	= d1 * d1 + d2 * d2 + d3 * d3;
	double e			= x1 * x1 + y1 * y1 + z1 * z1 - a * a - b * b;
	double f			= x1 * d1 + y1 * d2 + z1 * d3;
	double four_a_sqrd	= 4.0 * a * a;
	
	coeffs[0] = e * e - four_a_sqrd * (b * b - y1 * y1); 	// constant term
	coeffs[1] = 4.0 * f * e + 2.0 * four_a_sqrd * y1 * d2;
	coeffs[2] = 2.0 * sum_d_sqrd * e + 4.0 * f * f + four_a_sqrd * d2 * d2;
	coeffs[3] = 4.0 * sum_d_sqrd * f;
	coeffs[4] = sum_d_sqrd * sum_d_sqrd;  					// coefficient of t^4
	
	// find roots of the quartic equation
	
	int num_real_roots = SolveQuartic(coeffs, roots);
	
	bool	intersected = false;
	double 	t 		 	= kHugeValue;
	
	if (num_real_roots == 0)  // ray misses the torus
		return(false);
	
	// find the smallest root greater than kEpsilon, if any
	// the roots array is not sorted
			
	for (int j = 0; j < num_real_roots; j++)  
		if (roots[j] > kEpsilon) {
			intersected = true;
			if (roots[j] < t)
				t = roots[j];
		}
		
	if(!intersected)
		return (false);
		
	tmin 			 	= t;
	sr.local_hit_point 	= ray.o + t * ray.d;
	sr.normal 		 	= compute_normal(sr.local_hit_point);
	
	return (true);
}
Ejemplo n.º 2
0
bool ConcavePartTorus::shadow_hit(const Ray& ray, float& tmin) const {
  if (!shadows)
    return false;

  if (!bbox.hit(ray))
    return false;

  double x1 = ray.o.x; double y1 = ray.o.y; double z1 = ray.o.z;
  double d1 = ray.d.x; double d2 = ray.d.y; double d3 = ray.d.z;

  double coeffs[5];	// coefficient array for the quartic equation
  double roots[4];	// solution array for the quartic equation

  // define the coefficients of the quartic equation

  double sum_d_sqrd 	= d1 * d1 + d2 * d2 + d3 * d3;
  double e            = x1 * x1 + y1 * y1 + z1 * z1 - a * a - b * b;
  double f            = x1 * d1 + y1 * d2 + z1 * d3;
  double four_a_sqrd	= 4.0 * a * a;

  coeffs[0] = e * e - four_a_sqrd * (b * b - y1 * y1); 	// constant term
  coeffs[1] = 4.0 * f * e + 2.0 * four_a_sqrd * y1 * d2;
  coeffs[2] = 2.0 * sum_d_sqrd * e + 4.0 * f * f + four_a_sqrd * d2 * d2;
  coeffs[3] = 4.0 * sum_d_sqrd * f;
  coeffs[4] = sum_d_sqrd * sum_d_sqrd;  					// coefficient of t^4

  // find roots of the quartic equation
  int num_real_roots = SolveQuartic(coeffs, roots);

  bool intersected = false;
  double t = kHugeValue;

  if (num_real_roots == 0)  // ray misses the torus
    return false;

  // find the smallest root greater than kEpsilon, if any
  // the roots array is not sorted
  for (int j = 0; j < num_real_roots; j++) {
    if (roots[j] > kEpsilon) {
      if (roots[j] < t) {
        Vector3D hit = ray.o + roots[j] * ray.d;

        double phi = atan2(hit.x, hit.z);
        if (phi < 0.0)
          phi += TWO_PI;

        double theta = atan2(hit.y, sqrt(hit.x * hit.x + hit.z * hit.z) - a);
        if (theta < 0.0)
          theta += TWO_PI;

        bool good_theta;
        if (theta_max < theta_min) {
          good_theta = ((theta_min <= theta && theta <= 360)
                     || (0 <= theta && theta <= theta_max));
        } else {
          good_theta = (theta_min <= theta && theta <= theta_max);
        }
        if (phi_min <= phi && phi <= phi_max && good_theta) {
          intersected = true;
          t = roots[j];
        }
      }
    }
  }

  if(!intersected)
    return false;

  tmin = t;
  return true;
}