Ejemplo n.º 1
0
Archivo: BallN.hpp Proyecto: sidch/Thea
    bool rayIntersects(RayN<N, T> const & ray, T max_time = -1) const
    {
      if (max_time >= 0)
        return rayIntersectionTime(ray, max_time) >= 0;

      VectorT co = ray.getOrigin() - center;

      T c = co.squaredNorm() - radius * radius;
      if (c <= 0)  // origin is inside ball
        return true;

      T a = ray.getDirection().squaredNorm();
      T b = 2 * co.dot(ray.getDirection());

      // Solve quadratic a * t^2 + b * t + c = 0
      T b2 = b * b;
      T det = b2 - 4 * a * c;
      if (det < 0) return false;

      if (a > 0)
        return b <= 0 || det >= b2;
      else if (a < 0)
        return b >= 0 || det >= b2;
      else
        return false;
    }
Ejemplo n.º 2
0
      /**
       * Add a new set of update vectors to the history.
       *
       * @param yk Difference between the current and previous gradient vector.
       * @param sk Difference between the current and previous state vector.
       * @param reset Whether to reset the approximation, forgetting about
       * previous values.
       * @return In the case of a reset, returns the optimal scaling of the
       * initial Hessian
       * approximation which is useful for predicting step-sizes.
       **/
      inline Scalar update(const VectorT &yk, const VectorT &sk,
                           bool reset = false) {
        Scalar skyk = yk.dot(sk);

        Scalar B0fact;
        if (reset) {
          B0fact = yk.squaredNorm()/skyk;
          _buf.clear();
        } else {
          B0fact = 1.0;
        }

        // New updates are pushed to the "back" of the circular buffer
        Scalar invskyk = 1.0/skyk;
        _gammak = skyk/yk.squaredNorm();
        _buf.push_back();
        _buf.back() = boost::tie(invskyk, yk, sk);

        return B0fact;
      }
Ejemplo n.º 3
0
Archivo: BallN.hpp Proyecto: sidch/Thea
    T rayIntersectionTime(RayN<N, T> const & ray, T max_time = -1) const
    {
      VectorT co = ray.getOrigin() - center;

      T c = co.squaredNorm() - radius * radius;
      if (c <= 0)  // origin is inside ball
        return 0;

      // We could do an early test to see if the distance from the ray origin to the ball is less than
      // max_time * ray.getDirection().norm(), but it would involve a square root so might as well solve the quadratic.

      T a = ray.getDirection().squaredNorm();
      T b = 2 * co.dot(ray.getDirection());

      // Solve quadratic a * t^2 + b * t + c = 0
      T det = b * b - 4 * a * c;
      if (det < 0) return -1;

      T d = std::sqrt(det);
      T t = -1;
      if (a > 0)
      {
        T s0 = -b - d;
        if (s0 >= 0)
          t = s0 / (2 * a);
        else
        {
          T s1 = -b + d;
          if (s1 >= 0)
            t = s1 / (2 * a);
        }
      }
      else if (a < 0)
      {
        T s0 = -b + d;
        if (s0 <= 0)
          t = s0 / (2 * a);
        else
        {
          T s1 = -b - d;
          if (s1 <= 0)
            t = s1 / (2 * a);
        }
      }

      if (max_time >= 0 && t > max_time)
        return -1;
      else
        return t;
    }