inline bool on_offsetted(Point const& point, Piece const& piece) const { typedef typename strategy::side::services::default_strategy < typename cs_tag<Point>::type >::type side_strategy; geometry::equal_to<Point> comparator; for (int i = 1; i < piece.offsetted_count; i++) { Point const& previous = piece.robust_ring[i - 1]; Point const& current = piece.robust_ring[i]; // The robust ring contains duplicates, avoid applying side on them (will be 0) if (! comparator(previous, current)) { int const side = side_strategy::apply(previous, current, point); if (side == 0) { // Collinear, check if projection falls on it if (projection_on_segment(point, previous, current)) { return true; } } } } return false; }
std::tuple<MatrixXd, VectorXd> conforming_lloyd_2(const Density_2 &pl, const MatrixXd &X, const VectorXd &w, const MatrixXd &poly) { check_points_and_weights(X, w); size_t N = X.rows(); // create some room for return values: centroids and masses VectorXd m(N); MatrixXd c(N, 2); MA::lloyd(pl._t, pl._functions, X, w, m, c); std::vector<std::vector<Segment>> adjedges; std::vector<std::vector<size_t>> adjverts; compute_adjacencies_with_polygon(X, w, poly, adjedges, adjverts); //double lengthbd = 0; for (size_t i = 0; i < N; ++i) { if (adjverts[i].size() != 0) c.row(i) = poly.row(adjverts[i][0]); if (adjedges[i].size() != 0) { double mindist = 1e10; VectorXd proj; for (size_t j = 0; j < adjedges[i].size(); ++j) { Vector2d source (adjedges[i][j].source().x(), adjedges[i][j].source().y()); Vector2d dest (adjedges[i][j].target().x(), adjedges[i][j].target().y()); //lengthbd += (source-dest).norm(); auto p = projection_on_segment(source, dest, c.row(i)); double dp = (p - c.row(i)).squaredNorm(); if (mindist > dp) { mindist = dp; proj = p; } } c.row(i) = proj; } } //std::cerr << "length = " << lengthbd << "\n"; return std::make_tuple(c, m); }