Пример #1
0
Real
raySphereIntersectionTime(Ray3 const & ray, Vector3 const & center, Real radius)
{
  Vector3 pmc = ray.getOrigin() - center;

  double s[3];
  s[2] = ray.getDirection().squaredLength();
  s[1] = 2 * pmc.dot(ray.getDirection());
  s[0] = pmc.squaredLength() - radius * radius;

  double roots[2];
  int num_roots = Math::solveQuadratic(s[0], s[1], s[2], roots);

  double min_root = -1;
  for (int i = 0; i < num_roots; ++i)
    if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root))
      min_root = roots[i];

#if 0
  if (min_root >= 0)
    qDebug() << "min_root =" << min_root;
#endif

  return (Real)min_root;
}
Пример #2
0
Real
closestPtRayTriangle(Ray3 const & ray, Vector3 const & v0, Vector3 const & edge01, Vector3 const & edge02, Real & s,
                     Vector3 & c1, Vector3 & c2)
{
  Real sqdist = closestPtLineTriangle(Line3::fromPointAndDirection(ray.getOrigin(), ray.getDirection()), v0, edge01, edge02,
                                      s, c1, c2);
  if (s >= 0)
    return sqdist;

  // Not the most efficient way but the most convenient
  LocalTriangle3 tri(v0, v0 + edge01, v0 + edge02);
  s = 0;
  c1 = ray.getOrigin();
  c2 = tri.closestPoint(c1);

  return (c1 - c2).squaredLength();
}
Пример #3
0
Real
rayTorusIntersectionTime(Ray3 const & ray, Real torus_radius, Real torus_width)
{
  double r2pw2 = torus_radius * torus_radius + torus_width * torus_width;
  double r2mw2 = r2pw2 - 2 * torus_width * torus_width;

  Vector3 p2 = ray.getOrigin() * ray.getOrigin();
  Vector3 pu = ray.getOrigin() * ray.getDirection();
  Vector3 u2 = ray.getDirection() * ray.getDirection();

  double s[5];
  s[4] = u2[0] * (u2[0] + 2 * u2[1]) + u2[1] * (u2[1] + 2 * u2[2]) + u2[2] * (u2[2] + 2 * u2[0]);
  s[3] = 4 * (pu[0] + pu[1] + pu[2]) * (u2[0] + u2[1] + u2[2]);
  s[2] = 2 * (r2mw2 * u2[2] - r2pw2 * (u2[0] + u2[1]))
       + 8 * (pu[0] * pu[1] + pu[1] * pu[2] + pu[2] * pu[0])
       + 6 * (pu[0] * pu[0] + pu[1] * pu[1] + pu[2] * pu[2])
       + 2 * (p2[0] * (u2[1] + u2[2]) + p2[1] * (u2[2] + u2[0]) + p2[2] * (u2[0] + u2[1]));
  s[1] = 4 * (r2mw2 * pu[2] - r2pw2 * (pu[0] + pu[1]) + (p2[0] + p2[1] + p2[2]) * (pu[0] + pu[1] + pu[2]));
  s[0] = 2 * (r2mw2 * p2[2] - r2pw2 * (p2[0] + p2[1]) + p2[0] * p2[1] + p2[1] * p2[2] + p2[2] * p2[0])
       + p2[0] * p2[0] + p2[1] * p2[1] + p2[2] * p2[2] + r2mw2 * r2mw2;

  double roots[4];
  int num_roots = Math::solveQuartic(s[0], s[1], s[2], s[3], s[4], roots);

  double min_root = -1;
  for (int i = 0; i < num_roots; ++i)
    if (roots[i] >= 0 && (min_root < 0 || roots[i] < min_root))
      min_root = roots[i];

#if 0
  if (min_root >= 0)
    qDebug() << "min_root =" << min_root;
#endif

  return (Real)min_root;
}