#include "Point.hpp" #include "Line.hpp" #include "MultiPoint.hpp" #include "Int128.hpp" #include "BoundingBox.hpp" #include namespace Slic3r { std::vector transform(const std::vector& points, const Transform3f& t) { unsigned int vertices_count = (unsigned int)points.size(); if (vertices_count == 0) return std::vector(); unsigned int data_size = 3 * vertices_count * sizeof(float); Eigen::MatrixXf src(3, vertices_count); ::memcpy((void*)src.data(), (const void*)points.data(), data_size); Eigen::MatrixXf dst(3, vertices_count); dst = t * src.colwise().homogeneous(); std::vector ret_points(vertices_count, Vec3f::Zero()); ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size); return ret_points; } Pointf3s transform(const Pointf3s& points, const Transform3d& t) { unsigned int vertices_count = (unsigned int)points.size(); if (vertices_count == 0) return Pointf3s(); unsigned int data_size = 3 * vertices_count * sizeof(double); Eigen::MatrixXd src(3, vertices_count); ::memcpy((void*)src.data(), (const void*)points.data(), data_size); Eigen::MatrixXd dst(3, vertices_count); dst = t * src.colwise().homogeneous(); Pointf3s ret_points(vertices_count, Vec3d::Zero()); ::memcpy((void*)ret_points.data(), (const void*)dst.data(), data_size); return ret_points; } void Point::rotate(double angle, const Point ¢er) { double cur_x = (double)(*this)(0); double cur_y = (double)(*this)(1); double s = ::sin(angle); double c = ::cos(angle); double dx = cur_x - (double)center(0); double dy = cur_y - (double)center(1); (*this)(0) = (coord_t)round( (double)center(0) + c * dx - s * dy ); (*this)(1) = (coord_t)round( (double)center(1) + c * dy + s * dx ); } bool has_duplicate_points(std::vector &&pts) { std::sort(pts.begin(), pts.end()); for (size_t i = 1; i < pts.size(); ++ i) if (pts[i - 1] == pts[i]) return true; return false; } Points collect_duplicates(Points pts /* Copy */) { std::sort(pts.begin(), pts.end()); Points duplicits; const Point *prev = &pts.front(); for (size_t i = 1; i < pts.size(); ++i) { const Point *act = &pts[i]; if (*prev == *act) { // duplicit point if (!duplicits.empty() && duplicits.back() == *act) continue; // only unique duplicits duplicits.push_back(*act); } prev = act; } return duplicits; } BoundingBox get_extents(const Points &pts) { return BoundingBox(pts); } BoundingBox get_extents(const std::vector &pts) { BoundingBox bbox; for (const Points &p : pts) bbox.merge(get_extents(p)); return bbox; } BoundingBoxf get_extents(const std::vector &pts) { BoundingBoxf bbox; for (const Vec2d &p : pts) bbox.merge(p); return bbox; } int nearest_point_index(const Points &points, const Point &pt) { int64_t distance = std::numeric_limits::max(); int idx = -1; for (const Point &pt2 : points) { // If the X distance of the candidate is > than the total distance of the // best previous candidate, we know we don't want it. int64_t d = sqr(pt2.x() - pt.x()); if (d < distance) { // If the Y distance of the candidate is > than the total distance of the // best previous candidate, we know we don't want it. d += sqr(pt2.y() - pt.y()); if (d < distance) { idx = &pt2 - points.data(); distance = d; } } } return idx; } std::ostream& operator<<(std::ostream &stm, const Vec2d &pointf) { return stm << pointf(0) << "," << pointf(1); } namespace int128 { int orient(const Vec2crd &p1, const Vec2crd &p2, const Vec2crd &p3) { Slic3r::Vector v1(p2 - p1); Slic3r::Vector v2(p3 - p1); return Int128::sign_determinant_2x2_filtered(v1.x(), v1.y(), v2.x(), v2.y()); } int cross(const Vec2crd &v1, const Vec2crd &v2) { return Int128::sign_determinant_2x2_filtered(v1.x(), v1.y(), v2.x(), v2.y()); } } }