Boost-Geometry-Utils
view release on metacpan or search on metacpan
src/boost/polygon/voronoi_diagram.hpp view on Meta::CPAN
color_(0) {
if (is_linear)
color_ |= BIT_IS_LINEAR;
if (is_primary)
color_ |= BIT_IS_PRIMARY;
}
voronoi_cell_type* cell() { return cell_; }
const voronoi_cell_type* cell() const { return cell_; }
void cell(voronoi_cell_type* c) { cell_ = c; }
voronoi_vertex_type* vertex0() { return vertex_; }
const voronoi_vertex_type* vertex0() const { return vertex_; }
void vertex0(voronoi_vertex_type* v) { vertex_ = v; }
voronoi_vertex_type* vertex1() { return twin_->vertex0(); }
const voronoi_vertex_type* vertex1() const { return twin_->vertex0(); }
voronoi_edge_type* twin() { return twin_; }
const voronoi_edge_type* twin() const { return twin_; }
void twin(voronoi_edge_type* e) { twin_ = e; }
voronoi_edge_type* next() { return next_; }
const voronoi_edge_type* next() const { return next_; }
void next(voronoi_edge_type* e) { next_ = e; }
voronoi_edge_type* prev() { return prev_; }
const voronoi_edge_type* prev() const { return prev_; }
void prev(voronoi_edge_type* e) { prev_ = e; }
// Returns a pointer to the rotation next edge
// over the starting point of the half-edge.
voronoi_edge_type* rot_next() { return prev_->twin(); }
const voronoi_edge_type* rot_next() const { return prev_->twin(); }
// Returns a pointer to the rotation prev edge
// over the starting point of the half-edge.
voronoi_edge_type* rot_prev() { return twin_->next(); }
const voronoi_edge_type* rot_prev() const { return twin_->next(); }
// Returns true if the edge is finite (segment, parabolic arc).
// Returns false if the edge is infinite (ray, line).
bool is_finite() const { return vertex0() && vertex1(); }
// Returns true if the edge is infinite (ray, line).
// Returns false if the edge is finite (segment, parabolic arc).
bool is_infinite() const { return !vertex0() || !vertex1(); }
// Returns true if the edge is linear (segment, ray, line).
// Returns false if the edge is curved (parabolic arc).
bool is_linear() const {
return (color_ & BIT_IS_LINEAR) ? true : false;
}
// Returns true if the edge is curved (parabolic arc).
// Returns false if the edge is linear (segment, ray, line).
bool is_curved() const {
return (color_ & BIT_IS_LINEAR) ? false : true;
}
// Returns false if edge goes through the endpoint of the segment.
// Returns true else.
bool is_primary() const {
return (color_ & BIT_IS_PRIMARY) ? true : false;
}
// Returns true if edge goes through the endpoint of the segment.
// Returns false else.
bool is_secondary() const {
return (color_ & BIT_IS_PRIMARY) ? false : true;
}
color_type color() const { return color_ >> BITS_SHIFT; }
void color(color_type color) const {
color_ &= BITS_MASK;
color_ |= color << BITS_SHIFT;
}
private:
// 5 color bits are reserved.
enum Bits {
BIT_IS_LINEAR = 0x1, // linear is opposite to curved
BIT_IS_PRIMARY = 0x2, // primary is opposite to secondary
BITS_SHIFT = 0x5,
BITS_MASK = 0x1F
};
voronoi_cell_type* cell_;
voronoi_vertex_type* vertex_;
voronoi_edge_type* twin_;
voronoi_edge_type* next_;
voronoi_edge_type* prev_;
mutable color_type color_;
};
template <typename T>
struct voronoi_diagram_traits {
typedef T coordinate_type;
typedef voronoi_cell<coordinate_type> cell_type;
typedef voronoi_vertex<coordinate_type> vertex_type;
typedef voronoi_edge<coordinate_type> edge_type;
typedef class {
public:
enum { ULPS = 128 };
bool operator()(const vertex_type& v1, const vertex_type& v2) const {
return (ulp_cmp(v1.x(), v2.x(), ULPS) ==
detail::ulp_comparison<T>::EQUAL) &&
(ulp_cmp(v1.y(), v2.y(), ULPS) ==
detail::ulp_comparison<T>::EQUAL);
}
private:
typename detail::ulp_comparison<T> ulp_cmp;
} vertex_equality_predicate_type;
};
// Voronoi output data structure.
// CCW ordering is used on the faces perimeter and around the vertices.
template <typename T, typename TRAITS = voronoi_diagram_traits<T> >
class voronoi_diagram {
public:
typedef typename TRAITS::coordinate_type coordinate_type;
typedef typename TRAITS::cell_type cell_type;
typedef typename TRAITS::vertex_type vertex_type;
typedef typename TRAITS::edge_type edge_type;
typedef std::vector<cell_type> cell_container_type;
src/boost/polygon/voronoi_diagram.hpp view on Meta::CPAN
} else {
// Update prev/next pointers for the ray edges.
for (cell_iterator cell_it = cells_.begin();
cell_it != cells_.end(); ++cell_it) {
if (cell_it->is_degenerate())
continue;
// Move to the previous edge while
// it is possible in the CW direction.
edge_type* left_edge = cell_it->incident_edge();
while (left_edge->prev() != NULL) {
left_edge = left_edge->prev();
// Terminate if this is not a boundary cell.
if (left_edge == cell_it->incident_edge())
break;
}
if (left_edge->prev() != NULL)
continue;
edge_type* right_edge = cell_it->incident_edge();
while (right_edge->next() != NULL)
right_edge = right_edge->next();
left_edge->prev(right_edge);
right_edge->next(left_edge);
}
}
}
private:
typedef typename cell_container_type::iterator cell_iterator;
typedef typename vertex_container_type::iterator vertex_iterator;
typedef typename edge_container_type::iterator edge_iterator;
typedef typename TRAITS::vertex_equality_predicate_type
vertex_equality_predicate_type;
template <typename SEvent>
bool is_primary_edge(const SEvent& site1, const SEvent& site2) const {
bool flag1 = site1.is_segment();
bool flag2 = site2.is_segment();
if (flag1 && !flag2) {
return (site1.point0() != site2.point0()) &&
(site1.point1() != site2.point0());
}
if (!flag1 && flag2) {
return (site2.point0() != site1.point0()) &&
(site2.point1() != site1.point0());
}
return true;
}
template <typename SEvent>
bool is_linear_edge(const SEvent& site1, const SEvent& site2) const {
if (!is_primary_edge(site1, site2)) {
return true;
}
return !(site1.is_segment() ^ site2.is_segment());
}
// Remove degenerate edge.
void remove_edge(edge_type* edge) {
// Update the endpoints of the incident edges to the second vertex.
vertex_type* vertex = edge->vertex0();
edge_type* updated_edge = edge->twin()->rot_next();
while (updated_edge != edge->twin()) {
updated_edge->vertex0(vertex);
updated_edge = updated_edge->rot_next();
}
edge_type* edge1 = edge;
edge_type* edge2 = edge->twin();
edge_type* edge1_rot_prev = edge1->rot_prev();
edge_type* edge1_rot_next = edge1->rot_next();
edge_type* edge2_rot_prev = edge2->rot_prev();
edge_type* edge2_rot_next = edge2->rot_next();
// Update prev/next pointers for the incident edges.
edge1_rot_next->twin()->next(edge2_rot_prev);
edge2_rot_prev->prev(edge1_rot_next->twin());
edge1_rot_prev->prev(edge2_rot_next->twin());
edge2_rot_next->twin()->next(edge1_rot_prev);
}
cell_container_type cells_;
vertex_container_type vertices_;
edge_container_type edges_;
vertex_equality_predicate_type vertex_equality_predicate_;
// Disallow copy constructor and operator=
voronoi_diagram(const voronoi_diagram&);
void operator=(const voronoi_diagram&);
};
} // polygon
} // boost
#endif // BOOST_POLYGON_VORONOI_DIAGRAM
( run in 0.911 second using v1.01-cache-2.11-cpan-39bf76dae61 )