resolve_intersections.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #include "resolve_intersections.h"
  2. #include "subdivide_segments.h"
  3. #include "row_to_point.h"
  4. #include <igl/unique.h>
  5. #include <igl/list_to_matrix.h>
  6. #include <igl/copyleft/cgal/assign_scalar.h>
  7. #include <CGAL/Exact_predicates_exact_constructions_kernel.h>
  8. #include <CGAL/Segment_2.h>
  9. #include <CGAL/Point_2.h>
  10. #include <algorithm>
  11. #include <vector>
  12. template <
  13. typename DerivedV,
  14. typename DerivedE,
  15. typename DerivedVI,
  16. typename DerivedEI,
  17. typename DerivedJ,
  18. typename DerivedIM>
  19. IGL_INLINE void igl::copyleft::cgal::resolve_intersections(
  20. const Eigen::PlainObjectBase<DerivedV> & V,
  21. const Eigen::PlainObjectBase<DerivedE> & E,
  22. Eigen::PlainObjectBase<DerivedVI> & VI,
  23. Eigen::PlainObjectBase<DerivedEI> & EI,
  24. Eigen::PlainObjectBase<DerivedJ> & J,
  25. Eigen::PlainObjectBase<DerivedIM> & IM)
  26. {
  27. using namespace Eigen;
  28. using namespace igl;
  29. using namespace std;
  30. // Exact scalar type
  31. typedef CGAL::Epeck K;
  32. typedef K::FT EScalar;
  33. typedef CGAL::Segment_2<K> Segment_2;
  34. typedef CGAL::Point_2<K> Point_2;
  35. typedef Matrix<EScalar,Dynamic,Dynamic> MatrixXE;
  36. // Convert vertex positions to exact kernel
  37. MatrixXE VE(V.rows(),V.cols());
  38. for(int i = 0;i<V.rows();i++)
  39. {
  40. for(int j = 0;j<V.cols();j++)
  41. {
  42. VE(i,j) = V(i,j);
  43. }
  44. }
  45. const int m = E.rows();
  46. // resolve all intersections: silly O(n²) implementation
  47. std::vector<std::vector<Point_2> > steiner(m);
  48. for(int i = 0;i<m;i++)
  49. {
  50. Segment_2 si(row_to_point<K>(VE,E(i,0)),row_to_point<K>(VE,E(i,1)));
  51. steiner[i].push_back(si.vertex(0));
  52. steiner[i].push_back(si.vertex(1));
  53. for(int j = i+1;j<m;j++)
  54. {
  55. Segment_2 sj(row_to_point<K>(VE,E(j,0)),row_to_point<K>(VE,E(j,1)));
  56. // do they intersect?
  57. if(CGAL::do_intersect(si,sj))
  58. {
  59. CGAL::Object result = CGAL::intersection(si,sj);
  60. if(const Point_2 * p = CGAL::object_cast<Point_2 >(&result))
  61. {
  62. steiner[i].push_back(*p);
  63. steiner[j].push_back(*p);
  64. // add intersection point
  65. }else if(const Segment_2 * s = CGAL::object_cast<Segment_2 >(&result))
  66. {
  67. // add both endpoints
  68. steiner[i].push_back(s->vertex(0));
  69. steiner[j].push_back(s->vertex(0));
  70. steiner[i].push_back(s->vertex(1));
  71. steiner[j].push_back(s->vertex(1));
  72. }else
  73. {
  74. assert(false && "Unknown intersection type");
  75. }
  76. }
  77. }
  78. }
  79. subdivide_segments(V,E,steiner,VI,EI,J,IM);
  80. }