segment_segment_intersect.cpp 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. // This file is part of libigl, a simple c++ geometry processing library.
  2. //
  3. // Copyright (C) 2016 Francisca Gil Ureta <gilureta@cs.nyu.edu>
  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 "segment_segment_intersect.h"
  9. #include <Eigen/Geometry>
  10. template<typename DerivedSource, typename DerivedDir>
  11. IGL_INLINE bool igl::segments_intersect(
  12. const Eigen::PlainObjectBase <DerivedSource> &p,
  13. const Eigen::PlainObjectBase <DerivedDir> &r,
  14. const Eigen::PlainObjectBase <DerivedSource> &q,
  15. const Eigen::PlainObjectBase <DerivedDir> &s,
  16. double &a_t,
  17. double &a_u,
  18. double eps
  19. )
  20. {
  21. // http://stackoverflow.com/questions/563198/how-do-you-detect-where-two-line-segments-intersect
  22. // Search intersection between two segments
  23. // p + t*r : t \in [0,1]
  24. // q + u*s : u \in [0,1]
  25. // p + t * r = q + u * s // x s
  26. // t(r x s) = (q - p) x s
  27. // t = (q - p) x s / (r x s)
  28. // (r x s) ~ 0 --> directions are parallel, they will never cross
  29. Eigen::RowVector3d rxs = r.cross(s);
  30. if (rxs.norm() <= eps)
  31. return false;
  32. int sign;
  33. double u;
  34. // u = (q − p) × r / (r × s)
  35. Eigen::RowVector3d u1 = (q - p).cross(r);
  36. sign = ((u1.dot(rxs)) > 0) ? 1 : -1;
  37. u = u1.norm() / rxs.norm();
  38. u = u * sign;
  39. double t;
  40. // t = (q - p) x s / (r x s)
  41. Eigen::RowVector3d t1 = (q - p).cross(s);
  42. sign = ((t1.dot(rxs)) > 0) ? 1 : -1;
  43. t = t1.norm() / rxs.norm();
  44. t = t * sign;
  45. a_t = t;
  46. a_u = u;
  47. if ((u - 1.) > eps || u < -eps)
  48. return false;
  49. if ((t - 1.) > eps || t < -eps)
  50. return false;
  51. return true;
  52. };
  53. #ifdef IGL_STATIC_LIBRARY
  54. template bool igl::segments_intersect<Eigen::Matrix<double, 1, 3, 1, 1, 3>, Eigen::Matrix<double, 1, 3, 1, 1, 3> >(Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, Eigen::PlainObjectBase<Eigen::Matrix<double, 1, 3, 1, 1, 3> > const&, double&, double&, double);
  55. #endif