ray_sphere_intersect.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2014 Alec Jacobson <alecjacobson@gmail.com>
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public License
  6. // v. 2.0. If a copy of the MPL was not distributed with this file, You can
  7. // obtain one at http://mozilla.org/MPL/2.0/.
  8. #include "ray_sphere_intersect.h"
  9. template <
  10. typename Derivedo,
  11. typename Derivedd,
  12. typename Derivedc,
  13. typename r_type,
  14. typename t_type>
  15. IGL_INLINE int igl::ray_sphere_intersect(
  16. const Eigen::PlainObjectBase<Derivedo> & ao,
  17. const Eigen::PlainObjectBase<Derivedd> & d,
  18. const Eigen::PlainObjectBase<Derivedc> & ac,
  19. r_type r,
  20. t_type & t0,
  21. t_type & t1)
  22. {
  23. Eigen::Vector3d o = ao-ac;
  24. // http://wiki.cgsociety.org/index.php/Ray_Sphere_Intersection
  25. //Compute A, B and C coefficients
  26. double a = d.dot(d);
  27. double b = 2 * d.dot(o);
  28. double c = o.dot(o) - (r * r);
  29. //Find discriminant
  30. double disc = b * b - 4 * a * c;
  31. // if discriminant is negative there are no real roots, so return
  32. // false as ray misses sphere
  33. if (disc < 0)
  34. {
  35. return 0;
  36. }
  37. // compute q as described above
  38. double distSqrt = sqrt(disc);
  39. double q;
  40. if (b < 0)
  41. {
  42. q = (-b - distSqrt)/2.0;
  43. } else
  44. {
  45. q = (-b + distSqrt)/2.0;
  46. }
  47. // compute t0 and t1
  48. t0 = q / a;
  49. double _t1 = c/q;
  50. if(_t1 == t0)
  51. {
  52. return 1;
  53. }
  54. t1 = _t1;
  55. // make sure t0 is smaller than t1
  56. if (t0 > t1)
  57. {
  58. // if t0 is bigger than t1 swap them around
  59. double temp = t0;
  60. t0 = t1;
  61. t1 = temp;
  62. }
  63. return 2;
  64. }
  65. #ifdef IGL_STATIC_LIBRARY
  66. // Explicit template specialization
  67. template int igl::ray_sphere_intersect<Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, Eigen::Matrix<double, 3, 1, 0, 3, 1>, double, double>(Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 3, 1, 0, 3, 1> > const&, double, double&, double&);
  68. #endif