Offset curve from a Voronoi diagram: Fixed distance calculation
to a bisector of two segments.
This commit is contained in:
parent
ad7e7ae1cd
commit
3e0e537b7a
1 changed files with 27 additions and 10 deletions
|
@ -206,15 +206,15 @@ Polygons voronoi_offset(const VD &vd, const Lines &lines, double offset_distance
|
||||||
} else {
|
} else {
|
||||||
// Finite edge has valid points at both sides.
|
// Finite edge has valid points at both sides.
|
||||||
if (cell->contains_segment() && cell2->contains_segment()) {
|
if (cell->contains_segment() && cell2->contains_segment()) {
|
||||||
// This edge is a bisector of two line segments.
|
// This edge is a bisector of two line segments. Project v0, v1 onto one of the line segments.
|
||||||
d0 = std::hypot(v0->x() - line0.a.x(), v0->y() - line0.a.y());
|
Vec2d pt(line0.a.cast<double>());
|
||||||
d1 = std::hypot(v0->x() - line0.b.x(), v0->y() - line0.b.y());
|
Vec2d dir(line0.b.cast<double>() - pt);
|
||||||
if (d0 < d1)
|
Vec2d vec0 = Vec2d(v0->x(), v0->y()) - pt;
|
||||||
d1 = std::hypot(v1->x() - line0.a.x(), v1->y() - line0.a.y());
|
Vec2d vec1 = Vec2d(v1->x(), v1->y()) - pt;
|
||||||
else {
|
double l2 = dir.squaredNorm();
|
||||||
d0 = d1;
|
assert(l2 > 0.);
|
||||||
d1 = std::hypot(v1->x() - line0.b.x(), v1->y() - line0.b.y());
|
d0 = (dir * (vec0.dot(dir) / l2) - vec0).norm();
|
||||||
}
|
d1 = (dir * (vec1.dot(dir) / l2) - vec1).norm();
|
||||||
dmin = std::min(d0, d1);
|
dmin = std::min(d0, d1);
|
||||||
} else {
|
} else {
|
||||||
assert(cell->contains_point() || cell2->contains_point());
|
assert(cell->contains_point() || cell2->contains_point());
|
||||||
|
@ -303,6 +303,15 @@ Polygons voronoi_offset(const VD &vd, const Lines &lines, double offset_distance
|
||||||
return nullptr;
|
return nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
auto dist_to_site = [&lines](const VD::cell_type &cell, const Vec2d &point) {
|
||||||
|
const Line &line = lines[cell.source_index()];
|
||||||
|
return cell.contains_point() ?
|
||||||
|
(((cell.source_category() == boost::polygon::SOURCE_CATEGORY_SEGMENT_START_POINT) ? line.a : line.b).cast<double>() - point).norm() :
|
||||||
|
line.distance_to(point.cast<coord_t>());
|
||||||
|
};
|
||||||
|
#endif /* NDEBUG */
|
||||||
|
|
||||||
// Track the offset curves.
|
// Track the offset curves.
|
||||||
Polygons out;
|
Polygons out;
|
||||||
double angle_step = 2. * acos((offset_distance - discretization_error) / offset_distance);
|
double angle_step = 2. * acos((offset_distance - discretization_error) / offset_distance);
|
||||||
|
@ -329,7 +338,15 @@ Polygons voronoi_offset(const VD &vd, const Lines &lines, double offset_distance
|
||||||
const VD::cell_type *cell = edge->cell();
|
const VD::cell_type *cell = edge->cell();
|
||||||
Vec2d p1 = detail::voronoi_edge_offset_point(vd, lines, vertex_dist, edge_dist, *edge, offset_distance);
|
Vec2d p1 = detail::voronoi_edge_offset_point(vd, lines, vertex_dist, edge_dist, *edge, offset_distance);
|
||||||
Vec2d p2 = detail::voronoi_edge_offset_point(vd, lines, vertex_dist, edge_dist, *next_edge, offset_distance);
|
Vec2d p2 = detail::voronoi_edge_offset_point(vd, lines, vertex_dist, edge_dist, *next_edge, offset_distance);
|
||||||
if (cell->contains_point()) {
|
#ifndef NDEBUG
|
||||||
|
{
|
||||||
|
double err = dist_to_site(*cell, p1) - offset_distance;
|
||||||
|
assert(std::abs(err) < SCALED_EPSILON);
|
||||||
|
err = dist_to_site(*cell, p2) - offset_distance;
|
||||||
|
assert(std::abs(err) < SCALED_EPSILON);
|
||||||
|
}
|
||||||
|
#endif /* NDEBUG */
|
||||||
|
if (cell->contains_point()) {
|
||||||
// Discretize an arc from p1 to p2 with radius = offset_distance and discretization_error.
|
// Discretize an arc from p1 to p2 with radius = offset_distance and discretization_error.
|
||||||
// The arc should cover angle < PI.
|
// The arc should cover angle < PI.
|
||||||
//FIXME we should be able to produce correctly oriented output curves based on the first edge taken!
|
//FIXME we should be able to produce correctly oriented output curves based on the first edge taken!
|
||||||
|
|
Loading…
Reference in a new issue