-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Ease drawing of SDG duals #7976
Conversation
@Yvee1 I have added in 958eabe a comprehensive example on how to generate a cropped dual of a generic segment Delaunay graph, using both an inexact kernel during the computation (for speed) and an exact kernel with exact square roots in the construction of the dual (for precision of the positions). It might be of interest to you, or at least to see how you can extract your undiscretized parabolas. Let me know if you have any question. |
It doesn't draw per se or use basic viewers; it's more like "print": it only creates a list of segments that can e.g. be read by the polyhedron demo. But thanks for checking :) |
Thanks for the example. It is not clear to me though why you would want to use an exact kernel for drawing, could you elaborate on that? Also you seem to still discretize the parabolic segments. In case it is of any help to others, and to make my issue clearer: my temporary solution was to rewrite the template <class Stream,
class K,
class Gt = CGAL::Segment_Delaunay_graph_traits_2<K>,
class SDG = CGAL::Segment_Delaunay_graph_2<Gt>,
class ST = CGAL::Segment_Delaunay_graph_storage_traits_2<Gt>,
class D_S = CGAL::Triangulation_data_structure_2<CGAL::Segment_Delaunay_graph_vertex_base_2<ST>, CGAL::Segment_Delaunay_graph_face_base_2<Gt>>>
Stream& draw_dual_edge(const SDG& dg, typename D_S::Edge e, Stream& str)
{
typename Gt::Line_2 l;
typename Gt::Segment_2 s;
typename Gt::Ray_2 r;
CGAL::Parabola_segment_2<Gt> ps;
CGAL::Object o = dg.primal(e);
if (CGAL::assign(l, o)) str << l;
if (CGAL::assign(s, o)) str << s;
if (CGAL::assign(r, o)) str << r;
if (CGAL::assign(ps, o)) str << ps;
return str;
} Then I can handle it as follows. VoronoiDrawer& VoronoiDrawer::operator<<(const CGAL::Parabola_segment_2<Gt>& p) {
auto dir = p.line();
auto focus = p.center();
// Roundabout way to obtain start and end of parabolic segment because they are protected
std::vector<Gt::Point_2> pts;
p.generate_points(pts, Gt::FT(1000000));
auto start = pts.front();
auto end = pts.back();
auto control = CGAL::circumcenter(focus, dir.projection(start), dir.projection(end));
// Draw quadratic Bezier curve from start to end with control as control point
return *this;
} |
You can divide CGAL kernel functors into two categories: predicates (these are "yes"/"no" queries such as "is this geometry object intersecting that other geometric object?") and constructions (operations in which a new geometric entity appears). To build the correct SDG_2, you can use only exact predicates because the sites are given in input, and no new objects are created. A kernel that does not ensure exact constructions will be faster, so we use that during construction of the graph. Now, when you wish to draw the dual, you are creating new geometric entities: the Voronoi vertices. Of course you could use a kernel not providing exact constructions; almost always it will be good enough, but you will have no guarantees that it will, and sometimes it won't [*]. So instead you can use an kernel providing exact constructions, it's slower but it ensures that the geometric positions of the dual vertices are correct. Note that you need a kernel providing exact square roots like [*] Note that it is the same for the building of the SDG_2 itself: you could use a kernel that does not even provide exact predicates, and it might work just fine most of the time, but it's all about making sure things always work in all configurations.
Yes, this is just some code that I had lying around where I wanted the result to be segment polylines, hence I discretize the parabolas (but with an adaptive choice of discretization). Nevertheless, I thought it would be useful for you (and others) as you can just make your own example where instead of discretizing the parabola, you do whatever you want with the |
Right, thank you for the explanation. I did not realize that the SDG_2 performs no constructions; though, it makes sense as a Delaunay graph of points does not. It's strange though that I get an assertion violation when constructing a SDG_2 with inexact constructions but not with exact constructions (#7978), because if it would perform no constructions there should be no difference right? |
Successfully tested in CGAL-6.0-Ic-156 |
@MaelRL can one use the kerrnel without sqrt for the construction and the kernel with sqrt only where it is needed? |
Summary of Changes
Issue #7973 mentions improvements to do on the undocumented class
Parabola_segment_2
. To get started we make it a struct. Mael will add an example with some better drawing implementation.Release Management