MultiPoint.hpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. #ifndef slic3r_MultiPoint_hpp_
  2. #define slic3r_MultiPoint_hpp_
  3. #include "libslic3r.h"
  4. #include <algorithm>
  5. #include <vector>
  6. #include "Line.hpp"
  7. #include "Point.hpp"
  8. namespace Slic3r {
  9. class BoundingBox;
  10. class BoundingBox3;
  11. class MultiPoint
  12. {
  13. public:
  14. Points points;
  15. MultiPoint() {}
  16. MultiPoint(const MultiPoint &other) : points(other.points) {}
  17. MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {}
  18. MultiPoint(std::initializer_list<Point> list) : points(list) {}
  19. explicit MultiPoint(const Points &_points) : points(_points) {}
  20. MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; }
  21. MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; }
  22. void scale(double factor);
  23. void scale(double factor_x, double factor_y);
  24. void translate(double x, double y) { this->translate(Point(coord_t(x), coord_t(y))); }
  25. void translate(const Point &vector);
  26. void rotate(double angle) { this->rotate(cos(angle), sin(angle)); }
  27. void rotate(double cos_angle, double sin_angle);
  28. void rotate(double angle, const Point &center);
  29. void reverse() { std::reverse(this->points.begin(), this->points.end()); }
  30. const Point& first_point() const { return this->points.front(); }
  31. virtual const Point& last_point() const = 0;
  32. virtual Lines lines() const = 0;
  33. size_t size() const { return points.size(); }
  34. bool empty() const { return points.empty(); }
  35. double length() const;
  36. bool is_valid() const { return this->points.size() >= 2; }
  37. int find_point(const Point &point) const;
  38. bool has_boundary_point(const Point &point) const;
  39. int closest_point_index(const Point &point) const {
  40. int idx = -1;
  41. if (! this->points.empty()) {
  42. idx = 0;
  43. double dist_min = (point - this->points.front()).cast<double>().norm();
  44. for (int i = 1; i < int(this->points.size()); ++ i) {
  45. double d = (this->points[i] - point).cast<double>().norm();
  46. if (d < dist_min) {
  47. dist_min = d;
  48. idx = i;
  49. }
  50. }
  51. }
  52. return idx;
  53. }
  54. const Point* closest_point(const Point &point) const { return this->points.empty() ? nullptr : &this->points[this->closest_point_index(point)]; }
  55. BoundingBox bounding_box() const;
  56. // Return true if there are exact duplicates.
  57. bool has_duplicate_points() const;
  58. // Remove exact duplicates, return true if any duplicate has been removed.
  59. bool remove_duplicate_points();
  60. void append(const Point &point) { this->points.push_back(point); }
  61. void append(const Points &src) { this->append(src.begin(), src.end()); }
  62. void append(const Points::const_iterator &begin, const Points::const_iterator &end) { this->points.insert(this->points.end(), begin, end); }
  63. void append(Points &&src)
  64. {
  65. if (this->points.empty()) {
  66. this->points = std::move(src);
  67. } else {
  68. this->points.insert(this->points.end(), src.begin(), src.end());
  69. src.clear();
  70. }
  71. }
  72. bool intersection(const Line& line, Point* intersection) const;
  73. bool first_intersection(const Line& line, Point* intersection) const;
  74. bool intersections(const Line &line, Points *intersections) const;
  75. // Projection of a point onto the lines defined by the points.
  76. virtual Point point_projection(const Point &point) const;
  77. static Points _douglas_peucker(const Points& points, const double tolerance);
  78. static Points _douglas_peucker_plus(const Points& points, const double tolerance, const double min_length);
  79. static Points visivalingam(const Points& pts, const double& tolerance);
  80. };
  81. class MultiPoint3
  82. {
  83. public:
  84. Points3 points;
  85. void append(const Vec3crd& point) { this->points.push_back(point); }
  86. void translate(double x, double y);
  87. void translate(const Point& vector);
  88. virtual Lines3 lines() const = 0;
  89. double length() const;
  90. bool is_valid() const { return this->points.size() >= 2; }
  91. BoundingBox3 bounding_box() const;
  92. // Remove exact duplicates, return true if any duplicate has been removed.
  93. bool remove_duplicate_points();
  94. };
  95. extern BoundingBox get_extents(const MultiPoint &mp);
  96. extern BoundingBox get_extents_rotated(const std::vector<Point> &points, double angle);
  97. extern BoundingBox get_extents_rotated(const MultiPoint &mp, double angle);
  98. inline double length(const Points &pts) {
  99. double total = 0;
  100. if (! pts.empty()) {
  101. auto it = pts.begin();
  102. for (auto it_prev = it ++; it != pts.end(); ++ it, ++ it_prev)
  103. total += (*it - *it_prev).cast<double>().norm();
  104. }
  105. return total;
  106. }
  107. inline double area(const Points &polygon) {
  108. double area = 0.;
  109. for (size_t i = 0, j = polygon.size() - 1; i < polygon.size(); j = i ++)
  110. area += double(polygon[i](0) + polygon[j](0)) * double(polygon[i](1) - polygon[j](1));
  111. return area;
  112. }
  113. } // namespace Slic3r
  114. #endif