示例#1
0
    //! \brief A ray-inverse_sphere intersection test with backface culling.
    //!
    //! An inverse sphere means an "enclosing" sphere.
    //!
    //! \param T The origin of the ray relative to the inverse sphere
    //! center.
    //! \param D The direction/velocity of the ray.
    //! \param d The diameter of the inverse sphere.
    //! \return The time until the intersection, or HUGE_VAL if no intersection.
    inline double ray_inv_sphere_bfc(const math::Vector& T,
				     const math::Vector& D,
				     const double& r)
    {
      double D2 = D.nrm2();

      if (D2 == 0) return HUGE_VAL;
      
      double TD = T | D;
      double arg = TD * TD - D2 * (T.nrm2() - r * r);

      if (arg < 0) return HUGE_VAL;

      return (std::sqrt(arg) - TD) / D2;
    }
示例#2
0
    //! \brief A ray-sphere intersection test with backface culling.
    //!
    //! \param T The origin of the ray relative to the sphere center.
    //! \param D The direction/velocity of the ray.
    //! \param r The radius of the sphere.
    //! \return The time until the intersection, or HUGE_VAL if no intersection.
    inline double ray_sphere_bfc(const math::Vector& T,
				 const math::Vector& D,
				 const double& r)
    {
      double TD = (T | D);

      if (TD >= 0) return HUGE_VAL;
      
      double c = T.nrm2() - r * r;
      double arg = TD * TD - D.nrm2() * c;
      
      if (arg < 0) return HUGE_VAL;

      return  - c / (TD - std::sqrt(arg));
    }
示例#3
0
    /*! \brief A ray-rod intersection test.
      
      A rod is a cylinder which is not infinite, but of limited
      length. The cylinder is defined using a single base vertex at
      the center of the bottom circular face and an axial vector
      pointing from the base vertex to the top vertex. This test
      ignores the back face of the rod. It is used to detect when a
      ray will enter a rod.
     
      \param T The origin of the ray relative to the base vertex.
      \param D The direction/velocity of the ray.
      \param A The axial vector of the rod.
      \param r Radius of the rod.
      \return The time until the intersection, or HUGE_VAL if no intersection.
    */
    inline double ray_rod(math::Vector T, math::Vector D, const math::Vector& A, const double r)
    {
      double t = ray_cylinder(T, D, A / A.nrm(), r);
      double Tproj = ((T + t * D) | A);
      
      if ((Tproj < 0) || (Tproj > A.nrm2())) return HUGE_VAL;

      return t;
    }
示例#4
0
    /*! \brief A ray-inverse_rod intersection test.
    
      A rod is a cylinder which is not infinite, but of limited
      length. An inverse rod is used to test when a ray will exit a
      rod. The cylinder is defined using a single base vertex at the
      center of the bottom circular face and an axial vector
      pointing from the base vertex to the top vertex. This test
      ignores the back face of the rod.
     
      \param T The origin of the ray relative to the base vertex.
      \param D The direction/velocity of the ray.
      \param A The axial vector of the inverse rod.
      \param r Radius of the inverse rod.

      \tparam always_intersect If true, this will ensure that glancing
      ray's never escape the enclosing sphere by returning the time
      when the ray is nearest the sphere if the ray does not intersect
      the sphere.

      \return The time until the intersection, or HUGE_VAL if no intersection.
    */
    inline double ray_inv_rod(math::Vector T, math::Vector D, const math::Vector& A, const double r)
    {
      double t = ray_inv_cylinder(T, D, A / A.nrm(), r);

      M_throw() << "Confirm that this function is correct";

      double Tproj = ((T + t * D) | A);
      
      if ((Tproj < 0) || (Tproj > A.nrm2())) return HUGE_VAL;

      return t;
    }
示例#5
0
	std::array<double, nderivs> eval(const double dt = 0) const
	{
	  math::Vector u1new = Rodrigues(w1 * dt) * math::Vector(u1);
	  math::Vector u2new = Rodrigues(w2 * dt) * math::Vector(u2);

	  const double colldiam = 0.5 * (_diameter1 + _diameter2);
	  const double growthfactor = 1 + _invgamma * (_t + dt);
	  const math::Vector rij = r12 + dt * v12 + growthfactor * (u1new - u2new);
	  const math::Vector vij = v12 + growthfactor * ((w1 ^ u1new) - (w2 ^ u2new)) + _invgamma * (u1new - u2new);
	  const math::Vector aij = growthfactor * (-w1.nrm2() * u1new + w2.nrm2() * u2new) + 2 * _invgamma * ((w1 ^ u1new) - (w2 ^ u2new));
	  const math::Vector dotaij = growthfactor * (-w1.nrm2() * (w1 ^ u1new) + w2.nrm2() * (w2 ^ u2new)) + 3 * _invgamma * (-w1.nrm2() * u1new + w2.nrm2() * u2new);

	  std::array<double, nderivs> retval;
	  for (size_t i(0); i < nderivs; ++i)
	    switch (first_deriv + i) {
	    case 0: retval[i] = (rij | rij) - growthfactor * growthfactor * colldiam * colldiam; break;
	    case 1: retval[i] = 2 * (rij | vij) - 2 * _invgamma * growthfactor * colldiam * colldiam; break;
	    case 2: retval[i] = 2 * vij.nrm2() + 2 * (rij | aij) - 2 * _invgamma * _invgamma * colldiam * colldiam; break;
	    case 3: retval[i] = 6 * (vij | aij) + 2 * (rij | dotaij); break;
	    default:
	      M_throw() << "Invalid access";
	    }
	  return retval;
	}