std::vector<double> PolyBase::realRoots(const double epsilon)
/**
  Get just the real roots
  @param epsilon :: tolerance factor (-ve to use default)
  @return vector of the real roots (if any)
 */
{
  const double eps((epsilon > 0.0) ? epsilon : Eaccuracy);
  std::vector<std::complex<double>> Croots = calcRoots(epsilon);
  std::vector<double> Out;
  std::vector<std::complex<double>>::const_iterator vc;
  for (vc = Croots.begin(); vc != Croots.end(); ++vc) {
    if (fabs(vc->imag()) < eps)
      Out.push_back(vc->real());
  }
  return Out;
}
Beispiel #2
0
bool
Sphere::closestIntersectionModel(const Ray &ray, double maxLambda, RayIntersection& intersection) const
{
  /*
    A ray and a sphere intersect if and only if
      (o + lambda * d - c)^2 = r^2

    where
      o is the origin of the ray
      d is the direction vector of the ray
      c is the center of the sphere
      r is the radius of the sphere

    Since o and d are known, c = O and r = 1, we have
    a quadratic equation in lambda. We solve it using calcRoots()
    which is a slightly modified version of the classical
    quadratic formula (as described in [1]).

    [1] http://wiki.delphigl.com/index.php/Tutorial_Raytracing_-_Grundlagen_I#Quadratische_Gleichungen
  */

  // a, b and c are the constants in
  // a * lambda^2 + b * lambda + c = 0.
  double a = dot(ray.direction(), ray.direction());
  double b = 2 * dot(ray.direction(), ray.origin());
  double c = dot(ray.origin(), ray.origin()) - 1;

  // t1 and t2 are the solutions of our quadratic equation.
  // W.l.o.g. t1 <= t2 (calcRoots takes care of that)
  // calcRoots return the number of roots it found (zero, one or two).
  double t1, t2;
  int roots = calcRoots(a, b, c, t1, t2);

  bool doIntersect = false;
  if (roots > 0) {
    // There is a solution, we just need the (smallest) positve one.
    double lambda = t1 >= 0 ? t1 : t2;
    if (lambda >= 0.0 && lambda < maxLambda) {
      doIntersect = true;
      intersection = RayIntersection(ray, shared_from_this(), lambda, ray.pointOnRay(lambda), Vec3d(0,0,0));
    }
  }

  return doIntersect;
}