mirror of https://github.com/CGAL/cgal
Merge pull request #9036 from efifogel/Aos_2-approximate_unbounded-efif
Aos 2 approximate unbounded efif
This commit is contained in:
commit
837939c8ee
|
|
@ -6841,9 +6841,9 @@ arrangement-with-history from a file:
|
||||||
\cgalExample{Arrangement_on_surface_2/io_curve_history.cpp}
|
\cgalExample{Arrangement_on_surface_2/io_curve_history.cpp}
|
||||||
|
|
||||||
\cgalAdvancedBegin
|
\cgalAdvancedBegin
|
||||||
The arrangement package also includes the free functions `write(arr,
|
The arrangement package also includes the free functions
|
||||||
os, formatter)` and `read(arr, os, formatter)` that operate on a given
|
`write(arr, os, formatter)` and `read(arr, os, formatter)` that operate
|
||||||
arrangement-with-history instance `arr`. Both functions are
|
on a given arrangement-with-history instance `arr`. Both functions are
|
||||||
parameterized by a `formatter` object, which defines the I/O
|
parameterized by a `formatter` object, which defines the I/O
|
||||||
format. The package contains a template called,
|
format. The package contains a template called,
|
||||||
`Arr_with_hist_text_formatter<ArranagmentFormatter>`, which extends an
|
`Arr_with_hist_text_formatter<ArranagmentFormatter>`, which extends an
|
||||||
|
|
@ -6855,12 +6855,24 @@ and defines a simple textual input/output format.
|
||||||
\subsection arr_ssecarr_io_vis Drawing an Arrangement
|
\subsection arr_ssecarr_io_vis Drawing an Arrangement
|
||||||
<!-- ----------------------------------------------------------------------- -->
|
<!-- ----------------------------------------------------------------------- -->
|
||||||
|
|
||||||
An arrangement data structure can be visualized by calling the \link PkgArrangementOnSurface2Draw CGAL::draw<arr>() \endlink function as shown in the following example. This function opens a new window showing the given arrangement. A call to this function is blocking; that is, the program continues execution only after the user closes the window.
|
An arrangement data structure can be visualized by calling one of the
|
||||||
|
\link PkgArrangementOnSurface2Draw `CGAL::draw()` \endlink
|
||||||
|
overloaded template functions. Every variant opens a new window
|
||||||
|
showing the given arrangement. A call to any \link
|
||||||
|
PkgArrangementOnSurface2Draw `CGAL::draw()` \endlink function is
|
||||||
|
blocking; that is, the program continues execution only after the user
|
||||||
|
closes the window. The most simple variant accepts the arrangement to
|
||||||
|
draw and an optional string used as the title of the window. In the
|
||||||
|
following example we exploit a variant that also accepts an object the
|
||||||
|
type of which is an instance of the class template
|
||||||
|
`Graphics_scene_options`. It allows us to tune the drawings.
|
||||||
|
|
||||||
\cgalExample{Arrangement_on_surface_2/draw_arr.cpp}
|
\cgalExample{Arrangement_on_surface_2/draw_arr.cpp}
|
||||||
|
|
||||||
This function requires `CGAL_Qt6`, and is only available if the macro `CGAL_USE_BASIC_VIEWER` is defined.
|
This function requires `CGAL_Qt6`, and is only available if the macro
|
||||||
Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition `CGAL_USE_BASIC_VIEWER`.
|
`CGAL_USE_BASIC_VIEWER` is defined. Linking with the cmake target
|
||||||
|
`CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the
|
||||||
|
definition `CGAL_USE_BASIC_VIEWER`.
|
||||||
|
|
||||||
\cgalFigureBegin{aos_fig-draw_arr,draw_arr.png}
|
\cgalFigureBegin{aos_fig-draw_arr,draw_arr.png}
|
||||||
A snapshot of the window created by the program
|
A snapshot of the window created by the program
|
||||||
|
|
@ -6868,6 +6880,10 @@ A snapshot of the window created by the program
|
||||||
of 14 vertices, 15 edges, and 3 faces. Notice that the colors are generated at random.
|
of 14 vertices, 15 edges, and 3 faces. Notice that the colors are generated at random.
|
||||||
\cgalFigureEnd
|
\cgalFigureEnd
|
||||||
|
|
||||||
|
Another pair of overloaded \link PkgArrangementOnSurface2Draw
|
||||||
|
`CGAL::draw()` \endlink functions also accept a bounding box. Each
|
||||||
|
of these two variants can be ised to draw arrangements induced by
|
||||||
|
unbounded curves.
|
||||||
|
|
||||||
<!-- ======================================================================= -->
|
<!-- ======================================================================= -->
|
||||||
\section aos_sec-bgl Adapting to Boost Graphs
|
\section aos_sec-bgl Adapting to Boost Graphs
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ namespace CGAL {
|
||||||
* same direction as a precondition. Moreover, `Arr_circle_segment_traits_2`
|
* same direction as a precondition. Moreover, `Arr_circle_segment_traits_2`
|
||||||
* supports the merging of curves of opposite directions.
|
* supports the merging of curves of opposite directions.
|
||||||
*
|
*
|
||||||
* \cgalModels{AosTraits_2,AosApproximateTraits_2,AosDirectionalXMonotoneTraits_2}
|
* \cgalModels{AosTraits_2,AosApproximateTraits_2,AosApproximatePointTraits_2,AosDirectionalXMonotoneTraits_2}
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ namespace CGAL {
|
||||||
* to have the same direction as a precondition. Moreover, `Arr_conic_traits_2`
|
* to have the same direction as a precondition. Moreover, `Arr_conic_traits_2`
|
||||||
* supports the merging of curves of opposite directions.
|
* supports the merging of curves of opposite directions.
|
||||||
*
|
*
|
||||||
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosApproximateTraits_2,AosDirectionalXMonotoneTraits_2}
|
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosApproximateTraits_2,AosApproximatePointTraits_2,AosDirectionalXMonotoneTraits_2}
|
||||||
*
|
*
|
||||||
* \cgalHeading{Types}
|
* \cgalHeading{Types}
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace CGAL {
|
||||||
* we can find out its actual type and convert it to the respective kernel
|
* we can find out its actual type and convert it to the respective kernel
|
||||||
* object (say, to a `Kernel::Ray_2`).
|
* object (say, to a `Kernel::Ray_2`).
|
||||||
*
|
*
|
||||||
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosOpenBoundaryTraits_2}
|
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosOpenBoundaryTraits_2,AosApproximatePointTraits_2,AosApproximateTraits_2,AosApproximateUnboundedTraits_2}
|
||||||
*/
|
*/
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
class Arr_linear_traits_2 {
|
class Arr_linear_traits_2 {
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ namespace CGAL {
|
||||||
* same direction as a precondition. Moreover, `Arr_segment_traits_2` supports
|
* same direction as a precondition. Moreover, `Arr_segment_traits_2` supports
|
||||||
* the merging of curves of opposite directions.
|
* the merging of curves of opposite directions.
|
||||||
*
|
*
|
||||||
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosApproximateTraits_2,AosDirectionalXMonotoneTraits_2}
|
* \cgalModels{AosTraits_2,AosLandmarkTraits_2,AosApproximateTraits_2,AosApproximatePointTraits_2,AosDirectionalXMonotoneTraits_2}
|
||||||
*/
|
*/
|
||||||
template <typename Kernel>
|
template <typename Kernel>
|
||||||
class Arr_segment_traits_2 : public Kernel {
|
class Arr_segment_traits_2 : public Kernel {
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include <CGAL/Qt/Basic_viewer.h>
|
#include <CGAL/Qt/Basic_viewer.h>
|
||||||
|
|
||||||
|
#include "CGAL/Bbox_2.h"
|
||||||
|
|
||||||
#ifdef DOXYGEN_RUNNING
|
#ifdef DOXYGEN_RUNNING
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
@ -26,8 +28,8 @@ namespace CGAL {
|
||||||
/*! \ingroup PkgArrangementOnSurface2Draw
|
/*! \ingroup PkgArrangementOnSurface2Draw
|
||||||
|
|
||||||
* The function opens a new window and draws `arr`, an instance of the
|
* The function opens a new window and draws `arr`, an instance of the
|
||||||
* `CGAL::Arrangement_2` class template. Parameters of the drawing are taken
|
* `CGAL::Arrangement_on_surface_2` class template. Parameters of the drawing
|
||||||
* from the optional graphics scene options parameter.
|
* are taken from the optional graphics scene options parameter.
|
||||||
*
|
*
|
||||||
* A call to this function blocks the execution of the program until the drawing
|
* A call to this function blocks the execution of the program until the drawing
|
||||||
* window is closed. This function requires `CGAL_Qt6`, and is only available if
|
* window is closed. This function requires `CGAL_Qt6`, and is only available if
|
||||||
|
|
@ -35,57 +37,64 @@ namespace CGAL {
|
||||||
* `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition
|
* `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt6` and add the definition
|
||||||
* `CGAL_USE_BASIC_VIEWER`.
|
* `CGAL_USE_BASIC_VIEWER`.
|
||||||
*
|
*
|
||||||
* \tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement
|
* \tparam GeometryTraits a geometry traits type, a model of a 2D arrangement
|
||||||
* traits concept. At this point it must be an instance of either
|
* geometry traits concept. Observe that not all geometery-traits models are
|
||||||
* `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
|
* supported.
|
||||||
* \tparam Dcel the \dcel type, a model of the `AosDcel` concept.
|
*
|
||||||
|
* \tparam TopologyTraits a topology traits type, a model of the
|
||||||
|
* `AosTopologyTraits` concept.
|
||||||
|
*
|
||||||
* \tparam GSOptions a model of `GraphicsSceneOptions` concept.
|
* \tparam GSOptions a model of `GraphicsSceneOptions` concept.
|
||||||
*
|
*
|
||||||
* \param arr the 2D arrangement to draw.
|
* \param arr the 2D arrangement to draw.
|
||||||
* \param gso the graphics scene options parameter.
|
* \param bbox a bounding box in parameter space.
|
||||||
|
* \param gso the graphics scene options.
|
||||||
|
* \param title the optional title of the window.
|
||||||
*
|
*
|
||||||
* \sa `AosDcel`
|
|
||||||
* \sa `AosTraits_2`
|
* \sa `AosTraits_2`
|
||||||
|
* \sa `AosTopologyTraits`
|
||||||
|
* \sa `GraphicsSceneOptions`
|
||||||
*/
|
*/
|
||||||
template <typename GeometryTraits_2, typename Dcel, typename GSOptions>
|
|
||||||
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
|
template <typename GeometryTraits, typename TopologyTraits>
|
||||||
const GSOptions& gso);
|
void draw(const Arrangement_on_surface_2<GeometryTraits, TopologyTraits>& arr,
|
||||||
|
const Bbox_2& bbox, const GSOptions& gso,
|
||||||
|
const char* title = "2D Arrangement on Surface");
|
||||||
|
|
||||||
/*! \ingroup PkgArrangementOnSurface2Draw
|
/*! \ingroup PkgArrangementOnSurface2Draw
|
||||||
*
|
*
|
||||||
* A shortcut to `CGAL::draw(arr, Graphics_scene_options{})`.
|
* A shortcut to `CGAL::draw(arr, bbox, Graphics_scene_options<Aos,
|
||||||
|
* Aos::Vertex_const_handle, Aos::Halfedge_const_handle,
|
||||||
|
* Aos::Face_const_handle>{})`, where `Aos` is
|
||||||
|
* `Arrangement_on_surface_2<GeometryTraits, TopologyTraits>`.
|
||||||
*/
|
*/
|
||||||
template <typename GeometryTraits_2, typename Dcel>
|
|
||||||
void draw(const Arrangement_2<GeometryTraits_2, Dcel>& arr);
|
template <typename GeometryTraits, typename TopologyTraits>
|
||||||
|
void draw(const Arrangement_on_surface_2<GeometryTraits, TopologyTraits>& arr,
|
||||||
|
const Bbox_2& bbox, const char* title = "2D Arrangement on Surface");
|
||||||
|
|
||||||
/*! \ingroup PkgArrangementOnSurface2Draw
|
/*! \ingroup PkgArrangementOnSurface2Draw
|
||||||
*
|
*
|
||||||
* adds the vertices, edges and faces of `arr` into the given graphic scene
|
* Similar to `CGAL::draw(arr, bbox, gso)`, where the bounding box `bbox` is
|
||||||
* `gs`. Parameters of the cells are taken from the optional graphics scene
|
* computed to bound all points and curves of the arrangement in parameter
|
||||||
* options parameter `gso`. Note that `gs` is not cleared before being filled
|
* space.
|
||||||
* (to enable to draw several data structures in the same basic viewer).
|
|
||||||
*
|
|
||||||
* \tparam GeometryTraits_2 a geometry traits type, a model of a 2D arrangement
|
|
||||||
* traits concept. At this point it must be an instance of either
|
|
||||||
* `CGAL::Arr_segment_traits_2` or `CGAL::Arr_conic_traits_2`.
|
|
||||||
* \tparam Dcel the \dcel type, a model of the `AosDcel` concept.
|
|
||||||
* \tparam GSOptions a model of `GraphicsSceneOptions` concept.
|
|
||||||
*
|
|
||||||
* \param arr the 2D arrangement to draw.
|
|
||||||
* \param gs the graphic scene to fill.
|
|
||||||
* \param gso the graphics scene options parameter.
|
|
||||||
*/
|
*/
|
||||||
template <typename GeometryTraits_2, typename Dcel, typename GSOptions>
|
|
||||||
void add_to_graphics_scene(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
|
template <typename GeometryTraits, typename TopologyTraits>
|
||||||
CGAL::Graphics_scene& gs, const GSOptions& gso);
|
void draw(const Arrangement_on_surface_2<GeometryTraits, TopologyTraits>& arr,
|
||||||
|
const GSOptions& gso, const char* title = "2D Arrangement on Surface");
|
||||||
|
|
||||||
/*! \ingroup PkgArrangementOnSurface2Draw
|
/*! \ingroup PkgArrangementOnSurface2Draw
|
||||||
* A shortcut to `CGAL::add_to_graphics_scene(arr, gs,
|
*
|
||||||
* Graphics_scene_options{})`.
|
* A shortcut to `CGAL::draw(arr, Graphics_scene_options<Aos,
|
||||||
|
* Aos::Vertex_const_handle, Aos::Halfedge_const_handle,
|
||||||
|
* Aos::Face_const_handle>{})`, where `Aos` is
|
||||||
|
* `Arrangement_on_surface_2<GeometryTraits, TopologyTraits>`.
|
||||||
*/
|
*/
|
||||||
template <typename GeometryTraits_2, typename Dcel>
|
|
||||||
void add_to_graphics_scene(const Arrangement_2<GeometryTraits_2, Dcel>& arr,
|
template <typename GeometryTraits, typename TopologyTraits>
|
||||||
CGAL::Graphics_scene& gs);
|
void draw(const Arrangement_on_surface_2<GeometryTraits, TopologyTraits>& arr,
|
||||||
|
const char* title = "2D Arrangement on Surface");
|
||||||
|
|
||||||
} /* namespace CGAL */
|
} /* namespace CGAL */
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,8 +18,6 @@
|
||||||
* \cgalHasModels{CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>}
|
* \cgalHasModels{CGAL::Arr_rational_function_traits_2<AlgebraicKernel_d_1>}
|
||||||
* \cgalHasModelsEnd
|
* \cgalHasModelsEnd
|
||||||
*
|
*
|
||||||
* \sa `AosConstructXMonotoneCurveTraits_2`
|
|
||||||
* \sa `AosXMonotoneTraits_2`
|
|
||||||
* \sa `AosTraits_2`
|
* \sa `AosTraits_2`
|
||||||
*/
|
*/
|
||||||
class AosApproximatePointTraits_2 {
|
class AosApproximatePointTraits_2 {
|
||||||
|
|
@ -35,7 +33,7 @@ public:
|
||||||
/// \name Functor Types
|
/// \name Functor Types
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// models the concept `AosTraits::Approximate_2`.
|
/// models the concept `AosTraits::ApproximatePoint_2`.
|
||||||
typedef unspecified_type Approximate_2;
|
typedef unspecified_type Approximate_2;
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,9 @@
|
||||||
* \cgalHasModelsEnd
|
* \cgalHasModelsEnd
|
||||||
*
|
*
|
||||||
* \sa `AosApproximatePointTraits_2`
|
* \sa `AosApproximatePointTraits_2`
|
||||||
* \sa `draw()`
|
* \sa `AosConstructXMonotoneCurveTraits_2`
|
||||||
|
* \sa `AosXMonotoneTraits_2`
|
||||||
|
* \sa \link PkgArrangementOnSurface2Draw `CGAL::draw()`\endlink
|
||||||
*/
|
*/
|
||||||
class AosApproximateTraits_2 {
|
class AosApproximateTraits_2 {
|
||||||
public:
|
public:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
/*! \ingroup PkgArrangementOnSurface2ConceptsTraits
|
||||||
|
* \cgalConcept
|
||||||
|
*
|
||||||
|
* The concept `AosApproximateUnboundedTraits_2` refines the concept
|
||||||
|
* `AosApproximateTraits_2`. A model of this concept is able to approximate a
|
||||||
|
* curve constrained to a given bounding box (in addition to the ability to
|
||||||
|
* approximate a point and a curve without constraints).
|
||||||
|
*
|
||||||
|
* \cgalRefines{AosApproximateTraits_2}
|
||||||
|
*
|
||||||
|
* \cgalHasModelsBegin
|
||||||
|
* \cgalHasModels{CGAL::Arr_linear_traits_2<Kernel>}
|
||||||
|
* \cgalHasModelsEnd
|
||||||
|
*
|
||||||
|
* \sa `AosApproximateTraits_2`
|
||||||
|
* \sa \link PkgArrangementOnSurface2Draw `CGAL::draw()`\endlink
|
||||||
|
*/
|
||||||
|
class AosApproximateUnboundedTraits_2 {
|
||||||
|
public:
|
||||||
|
/// \name Types
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Functor Types
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/// models the concept `AosTraits::ApproximateUnbounded_2`.
|
||||||
|
typedef unspecified_type Approximate_2;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
/// \name Accessing Functor Objects
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
///
|
||||||
|
Approximate_2 approximate_2_object() const;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
namespace AosTraits {
|
||||||
|
|
||||||
|
/*! \ingroup PkgArrangementOnSurface2ConceptsFunctionObjects
|
||||||
|
* \cgalConcept
|
||||||
|
*
|
||||||
|
* \cgalRefines{Functor}
|
||||||
|
*
|
||||||
|
* \cgalHasModelsBegin
|
||||||
|
* \cgalHasModels{AosApproximatePointTraits_2::Approximate_2}
|
||||||
|
* \cgalHasModels{AosApproximateTraits_2::Approximate_2}
|
||||||
|
* \cgalHasModelsEnd
|
||||||
|
*/
|
||||||
|
class ApproximatePoint_2 {
|
||||||
|
public:
|
||||||
|
/// \name Operations
|
||||||
|
/// A model of this concept must provide:
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*! obtains an approximation of `p`'s \f$x\f$-coordinate (if `i == 0`), or of
|
||||||
|
* `p`'s \f$y\f$-coordinate (if `i == 1`).
|
||||||
|
* \pre `i` is either 0 or 1.
|
||||||
|
*/
|
||||||
|
Approximate_number_type operator()(AosTraits::Point_2 p, int i);
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
}; /* end AosTraits::Approximate_2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
namespace AosTraits {
|
||||||
|
|
||||||
|
/*! \ingroup PkgArrangementOnSurface2ConceptsFunctionObjects
|
||||||
|
* \cgalConcept
|
||||||
|
*
|
||||||
|
* \cgalRefines{Approximate_2}
|
||||||
|
*
|
||||||
|
* \cgalHasModelsBegin
|
||||||
|
* \cgalHasModels{AosApproximatePointTraits_2::Approximate_2}
|
||||||
|
* \cgalHasModels{AosApproximateTraits_2::Approximate_2}
|
||||||
|
* \cgalHasModels{AosApproximateUnboundedTraits_2::Approximate_2}
|
||||||
|
* \cgalHasModelsEnd
|
||||||
|
*/
|
||||||
|
class ApproximateUnbounded_2 {
|
||||||
|
public:
|
||||||
|
/// \name Operations
|
||||||
|
/// A model of this concept must provide:
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/*! approximates a given \f$x\f$-monotone curve constrained to a bounding
|
||||||
|
* box. It computes one or more sequences of approximate points that represent
|
||||||
|
* the disconnected portions of a polyline that approximates `xcv` within the
|
||||||
|
* bounding box `bbox`, and inserts them into output containers given through
|
||||||
|
* the output iterator `oi`. The first point of the first sequence and the
|
||||||
|
* last point of the last sequence are always approximations of the endpoints
|
||||||
|
* of the given curve.
|
||||||
|
*
|
||||||
|
* \param xcv The exact \f$x\f$-monotone curve.
|
||||||
|
* \param error The error bound of the polyline approximation. This is the
|
||||||
|
* Hausdorff distance between the curve and the polyline that
|
||||||
|
* approximates the curve.
|
||||||
|
* \param oi An output iterator for the output containers.
|
||||||
|
* \param bbox the bounding box.
|
||||||
|
* \param l2r A Boolean flag that indicates whether the curve direction is
|
||||||
|
* left to right.
|
||||||
|
* \return The past-the-end iterator of the output container.
|
||||||
|
*
|
||||||
|
* \pre Dereferencing `oi` must yield an object the type of which is a
|
||||||
|
* container, where the value type of this container is
|
||||||
|
* `AosApproximateTraits_2::Approximate_point_2`.
|
||||||
|
*/
|
||||||
|
template <typename OutputIterator>
|
||||||
|
OutputIterator operator()(const X_monotone_curve_2& xcv, double error, OutputIterator oi,
|
||||||
|
const Bbox_2& bbox, bool l2r = true) const;
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
}; /* end AosTraits::Approximate_2 */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@ namespace AosTraits {
|
||||||
/*! \ingroup PkgArrangementOnSurface2ConceptsFunctionObjects
|
/*! \ingroup PkgArrangementOnSurface2ConceptsFunctionObjects
|
||||||
* \cgalConcept
|
* \cgalConcept
|
||||||
*
|
*
|
||||||
* \cgalRefines{Functor}
|
* \cgalRefines{ApproximatePoint_2}
|
||||||
*
|
*
|
||||||
* \cgalHasModelsBegin
|
* \cgalHasModelsBegin
|
||||||
* \cgalHasModels{AosApproximatePointTraits_2::Approximate_2}
|
* \cgalHasModels{AosApproximatePointTraits_2::Approximate_2}
|
||||||
|
|
@ -16,15 +16,9 @@ public:
|
||||||
/// A model of this concept must provide:
|
/// A model of this concept must provide:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/*! obtains an approximation of `p`'s \f$x\f$-coordinate (if `i == 0`), or of
|
|
||||||
* `p`'s \f$y\f$-coordinate (if `i == 1`).
|
|
||||||
* \pre `i` is either 0 or 1.
|
|
||||||
*/
|
|
||||||
CGAL::Approximate_number_type operator()(AosTraits::Point_2 p, int i);
|
|
||||||
|
|
||||||
/*! obtains an approximation of `p`.
|
/*! obtains an approximation of `p`.
|
||||||
*/
|
*/
|
||||||
CGAL::Approximate_point_2 operator()(AosTraits::Point_2 p);
|
Approximate_point_2 operator()(AosTraits::Point_2 p);
|
||||||
|
|
||||||
/*! approximates a given \f$x\f$-monotone curve. It computes a sequence of
|
/*! approximates a given \f$x\f$-monotone curve. It computes a sequence of
|
||||||
* approximate points that represent an approximate polyline, and inserts
|
* approximate points that represent an approximate polyline, and inserts
|
||||||
|
|
@ -42,7 +36,7 @@ public:
|
||||||
* \return The past-the-end iterator of the output container.
|
* \return The past-the-end iterator of the output container.
|
||||||
*
|
*
|
||||||
* \pre Dereferencing `oi` must yield an object of type
|
* \pre Dereferencing `oi` must yield an object of type
|
||||||
* `Arr_conic_traits_2::Approximate_point_2`.
|
* `AosApproximateTraits_2::Approximate_point_2`.
|
||||||
*/
|
*/
|
||||||
template <typename OutputIterator>
|
template <typename OutputIterator>
|
||||||
OutputIterator operator()(const X_monotone_curve_2& xcv, double error,
|
OutputIterator operator()(const X_monotone_curve_2& xcv, double error,
|
||||||
|
|
|
||||||
|
|
@ -113,6 +113,7 @@ implemented as peripheral classes or as free (global) functions.
|
||||||
|
|
||||||
- `AosApproximateTraits_2`
|
- `AosApproximateTraits_2`
|
||||||
- `AosApproximatePointTraits_2`
|
- `AosApproximatePointTraits_2`
|
||||||
|
- `AosApproximateUnboundedTraits_2`
|
||||||
- `AosBasicTopologyTraits`
|
- `AosBasicTopologyTraits`
|
||||||
- `AosBasicTraits_2`
|
- `AosBasicTraits_2`
|
||||||
- `AosBottomSideTraits_2`
|
- `AosBottomSideTraits_2`
|
||||||
|
|
@ -167,6 +168,8 @@ implemented as peripheral classes or as free (global) functions.
|
||||||
\cgalCRPSection{Function Object Concepts}
|
\cgalCRPSection{Function Object Concepts}
|
||||||
|
|
||||||
- `AosTraits::Approximate_2`
|
- `AosTraits::Approximate_2`
|
||||||
|
- `AosTraits::ApproximatePoint_2`
|
||||||
|
- `AosTraits::ApproximateUnbounded_2`
|
||||||
- `AosTraits::AreMergeable_2`
|
- `AosTraits::AreMergeable_2`
|
||||||
- `AosTraits::CompareX_2`
|
- `AosTraits::CompareX_2`
|
||||||
- `AosTraits::CompareXy_2`
|
- `AosTraits::CompareXy_2`
|
||||||
|
|
@ -262,6 +265,6 @@ implemented as peripheral classes or as free (global) functions.
|
||||||
- \link PkgArrangementOnSurface2op_right_shift `CGAL::operator<<` \endlink
|
- \link PkgArrangementOnSurface2op_right_shift `CGAL::operator<<` \endlink
|
||||||
|
|
||||||
\cgalCRPSection{Draw an `Arrangemen_2` object}
|
\cgalCRPSection{Draw an `Arrangemen_2` object}
|
||||||
- \link PkgArrangementOnSurface2Draw CGAL::draw<>() \endlink
|
- \link PkgArrangementOnSurface2Draw CGAL::draw<>() \endlink
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include <CGAL/Cartesian.h>
|
||||||
#include <CGAL/tags.h>
|
#include <CGAL/tags.h>
|
||||||
#include <CGAL/intersections.h>
|
#include <CGAL/intersections.h>
|
||||||
#include <CGAL/Arr_tags.h>
|
#include <CGAL/Arr_tags.h>
|
||||||
|
|
@ -1517,9 +1518,24 @@ public:
|
||||||
|
|
||||||
/// \name Functor definitions for the landmarks point-location strategy.
|
/// \name Functor definitions for the landmarks point-location strategy.
|
||||||
//@{
|
//@{
|
||||||
typedef double Approximate_number_type;
|
typedef double Approximate_number_type;
|
||||||
|
typedef CGAL::Cartesian<Approximate_number_type> Approximate_kernel;
|
||||||
|
typedef Approximate_kernel::Point_2 Approximate_point_2;
|
||||||
|
|
||||||
class Approximate_2 {
|
class Approximate_2 {
|
||||||
|
protected:
|
||||||
|
using Traits = Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
|
/*! The traits (in case it has state) */
|
||||||
|
const Traits& m_traits;
|
||||||
|
|
||||||
|
/*! constructs
|
||||||
|
* \param traits the traits.
|
||||||
|
*/
|
||||||
|
Approximate_2(const Traits& traits) : m_traits(traits) {}
|
||||||
|
|
||||||
|
friend class Arr_linear_traits_2<Kernel>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/*! obtains an approximation of a point coordinate.
|
/*! obtains an approximation of a point coordinate.
|
||||||
* \param p The exact point.
|
* \param p The exact point.
|
||||||
|
|
@ -1533,10 +1549,102 @@ public:
|
||||||
CGAL_precondition((i == 0) || (i == 1));
|
CGAL_precondition((i == 0) || (i == 1));
|
||||||
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
|
return (i == 0) ? CGAL::to_double(p.x()) : CGAL::to_double(p.y());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*! obtains an approximation of a point.
|
||||||
|
*/
|
||||||
|
Approximate_point_2 operator()(const Point_2& p) const
|
||||||
|
{ return Approximate_point_2(operator()(p, 0), operator()(p, 1)); }
|
||||||
|
|
||||||
|
/*! obtains an approximation of an \f$x\f$-monotone curve.
|
||||||
|
*/
|
||||||
|
template <typename OutputIterator>
|
||||||
|
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
|
||||||
|
OutputIterator oi, bool l2r = true) const {
|
||||||
|
auto min_vertex = m_traits.construct_min_vertex_2_object();
|
||||||
|
auto max_vertex = m_traits.construct_max_vertex_2_object();
|
||||||
|
const auto& src = (l2r) ? min_vertex(xcv) : max_vertex(xcv);
|
||||||
|
const auto& trg = (l2r) ? max_vertex(xcv) : min_vertex(xcv);
|
||||||
|
auto xs = CGAL::to_double(src.x());
|
||||||
|
auto ys = CGAL::to_double(src.y());
|
||||||
|
auto xt = CGAL::to_double(trg.x());
|
||||||
|
auto yt = CGAL::to_double(trg.y());
|
||||||
|
*oi++ = Approximate_point_2(xs, ys);
|
||||||
|
*oi++ = Approximate_point_2(xt, yt);
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! obtains an approximation of an \f$x\f$-monotone curve.
|
||||||
|
*/
|
||||||
|
template <typename OutputIterator>
|
||||||
|
OutputIterator operator()(const X_monotone_curve_2& xcv, double /* error */,
|
||||||
|
OutputIterator oi, const Bbox_2& bbox,
|
||||||
|
bool l2r = true) const
|
||||||
|
{
|
||||||
|
using Approx_pnt = Approximate_point_2;
|
||||||
|
using Approx_seg = Approximate_kernel::Segment_2;
|
||||||
|
using Approx_ray = Approximate_kernel::Ray_2;
|
||||||
|
using Approx_lin = Approximate_kernel::Line_2;
|
||||||
|
auto xmin = bbox.xmin();
|
||||||
|
auto ymin = bbox.ymin();
|
||||||
|
auto xmax = bbox.xmax();
|
||||||
|
auto ymax = bbox.ymax();
|
||||||
|
Approximate_kernel::Iso_rectangle_2 rect(xmin, ymin, xmax, ymax);
|
||||||
|
if (xcv.is_ray()) {
|
||||||
|
auto ray = xcv.ray();
|
||||||
|
Kernel kernel;
|
||||||
|
auto construct_vertex = kernel.construct_point_on_2_object();
|
||||||
|
Approx_pnt s = this->operator()(construct_vertex(ray, 0));
|
||||||
|
Approx_pnt t = this->operator()(construct_vertex(ray, 1));
|
||||||
|
const auto result = CGAL::intersection(rect, Approx_ray(s, t));
|
||||||
|
if (! result) return oi;
|
||||||
|
|
||||||
|
if (const auto* res_seg = std::get_if<Approx_seg>(&*result)) {
|
||||||
|
*oi++ = l2r ? (res_seg->min)() : (res_seg->max)();
|
||||||
|
*oi++ = l2r ? (res_seg->max)() : (res_seg->min)();
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
const auto* res_pnt = std::get_if<Approx_pnt>(&*result);
|
||||||
|
CGAL_assertion(res_pnt != nullptr);
|
||||||
|
*oi++ = *res_pnt;
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
if (xcv.is_line()) {
|
||||||
|
const Line_2 & supp_line = xcv.supp_line();
|
||||||
|
Approx_lin approx_supp_line(
|
||||||
|
CGAL::to_double(supp_line.a()),
|
||||||
|
CGAL::to_double(supp_line.b()),
|
||||||
|
CGAL::to_double(supp_line.c()));
|
||||||
|
const auto result = CGAL::intersection(rect, approx_supp_line);
|
||||||
|
if (! result) return oi;
|
||||||
|
|
||||||
|
if (const auto* res_seg = std::get_if<Approx_seg>(&*result)) {
|
||||||
|
*oi++ = l2r ? (res_seg->min)() : (res_seg->max)();
|
||||||
|
*oi++ = l2r ? (res_seg->max)() : (res_seg->min)();
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
const auto* res_pnt = std::get_if<Approx_pnt>(&*result);
|
||||||
|
CGAL_assertion(res_pnt != nullptr);
|
||||||
|
*oi++ = *res_pnt;
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
Approx_seg seg(this->operator()(xcv.source()), this->operator()(xcv.target()));
|
||||||
|
const auto result = CGAL::intersection(rect, seg);
|
||||||
|
if (! result) return oi;
|
||||||
|
|
||||||
|
if (const auto* res_seg = std::get_if<Approx_seg>(&*result)) {
|
||||||
|
*oi++ = l2r ? (res_seg->min)() : (res_seg->max)();
|
||||||
|
*oi++ = l2r ? (res_seg->max)() : (res_seg->min)();
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
|
const auto* res_pnt = std::get_if<Approx_pnt>(&*result);
|
||||||
|
CGAL_assertion(res_pnt != nullptr);
|
||||||
|
*oi++ = *res_pnt;
|
||||||
|
return oi;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! obtains an `Approximate_2` functor object. */
|
/*! obtains an `Approximate_2` functor object. */
|
||||||
Approximate_2 approximate_2_object() const { return Approximate_2(); }
|
Approximate_2 approximate_2_object() const { return Approximate_2(*this); }
|
||||||
|
|
||||||
//! Functor
|
//! Functor
|
||||||
class Construct_x_monotone_curve_2 {
|
class Construct_x_monotone_curve_2 {
|
||||||
|
|
|
||||||
|
|
@ -37,58 +37,55 @@
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
namespace draw_function_for_arrangement_2
|
namespace draw_aos {
|
||||||
{
|
|
||||||
template<typename Arr, typename GSOptions>
|
|
||||||
class Draw_arr_tool
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
using Halfedge_const_handle=typename Arr::Halfedge_const_handle;
|
|
||||||
using Vertex_const_handle=typename Arr::Vertex_const_handle;
|
|
||||||
using Face_const_handle=typename Arr::Face_const_handle;
|
|
||||||
using Ccb_halfedge_const_circulator=typename Arr::Ccb_halfedge_const_circulator;
|
|
||||||
using Inner_ccb_const_iterator=typename Arr::Inner_ccb_const_iterator;
|
|
||||||
using Outer_ccb_const_iterator=typename Arr::Outer_ccb_const_iterator;
|
|
||||||
using Gt=typename Arr::Geometry_traits_2;
|
|
||||||
using Point=typename Arr::Point_2;
|
|
||||||
using X_monotone_curve = typename Arr::X_monotone_curve_2;
|
|
||||||
|
|
||||||
Draw_arr_tool(Arr& a_aos, CGAL::Graphics_scene& a_gs, const GSOptions& a_gso):
|
template<typename Arr, typename GSOptions>
|
||||||
m_aos(a_aos), m_gs(a_gs), m_gso(a_gso)
|
class Draw_arr_tool {
|
||||||
{}
|
public:
|
||||||
|
using Halfedge_const_handle=typename Arr::Halfedge_const_handle;
|
||||||
|
using Vertex_const_handle=typename Arr::Vertex_const_handle;
|
||||||
|
using Face_const_handle=typename Arr::Face_const_handle;
|
||||||
|
using Ccb_halfedge_const_circulator=typename Arr::Ccb_halfedge_const_circulator;
|
||||||
|
using Inner_ccb_const_iterator=typename Arr::Inner_ccb_const_iterator;
|
||||||
|
using Outer_ccb_const_iterator=typename Arr::Outer_ccb_const_iterator;
|
||||||
|
using Gt=typename Arr::Geometry_traits_2;
|
||||||
|
using Point=typename Arr::Point_2;
|
||||||
|
using X_monotone_curve = typename Arr::X_monotone_curve_2;
|
||||||
|
|
||||||
/// Add a face.
|
Draw_arr_tool(Arr& a_aos, CGAL::Graphics_scene& a_gs, const GSOptions& a_gso):
|
||||||
void add_face(Face_const_handle face)
|
m_aos(a_aos), m_gs(a_gs), m_gso(a_gso)
|
||||||
{
|
{}
|
||||||
// std::cout << "add_face()\n";
|
|
||||||
for (Inner_ccb_const_iterator it = face->inner_ccbs_begin();
|
|
||||||
it != face->inner_ccbs_end(); ++it)
|
|
||||||
{ add_ccb(*it); }
|
|
||||||
|
|
||||||
|
//! adds a face.
|
||||||
|
void add_face(Face_const_handle face) {
|
||||||
|
// std::cout << "add_face()\n";
|
||||||
|
for (Inner_ccb_const_iterator it = face->inner_ccbs_begin();
|
||||||
|
it != face->inner_ccbs_end(); ++it)
|
||||||
|
add_ccb(*it);
|
||||||
|
|
||||||
|
if (! face->is_unbounded()) {
|
||||||
for (Outer_ccb_const_iterator it = face->outer_ccbs_begin();
|
for (Outer_ccb_const_iterator it = face->outer_ccbs_begin();
|
||||||
it != face->outer_ccbs_end(); ++it)
|
it != face->outer_ccbs_end(); ++it) {
|
||||||
{
|
|
||||||
add_ccb(*it);
|
add_ccb(*it);
|
||||||
draw_region(*it);
|
draw_region(*it);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Add a Connected Component of the Boundary.
|
//! adds a Connected Component of the Boundary.
|
||||||
void add_ccb(Ccb_halfedge_const_circulator circ)
|
void add_ccb(Ccb_halfedge_const_circulator circ) {
|
||||||
{
|
// std::cout << "add_ccb()\n";
|
||||||
// std::cout << "add_ccb()\n";
|
auto curr = circ;
|
||||||
auto curr = circ;
|
do {
|
||||||
do {
|
auto new_face = curr->twin()->face();
|
||||||
auto new_face = curr->twin()->face();
|
if (m_visited.find(new_face) != m_visited.end()) continue;
|
||||||
if (m_visited.find(new_face) != m_visited.end()) continue;
|
m_visited[new_face] = true;
|
||||||
m_visited[new_face] = true;
|
add_face(new_face);
|
||||||
add_face(new_face);
|
} while (++curr != circ);
|
||||||
} while (++curr != circ);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
///! Draw a region.
|
//! draws a region.
|
||||||
void draw_region(Ccb_halfedge_const_circulator circ)
|
void draw_region(Ccb_halfedge_const_circulator circ) {
|
||||||
{
|
|
||||||
// std::cout << "draw_region()\n";
|
// std::cout << "draw_region()\n";
|
||||||
/* Check whether the traits has a member function called
|
/* Check whether the traits has a member function called
|
||||||
* approximate_2_object() and if so check whether the return type, namely
|
* approximate_2_object() and if so check whether the return type, namely
|
||||||
|
|
@ -105,318 +102,300 @@ namespace draw_function_for_arrangement_2
|
||||||
*
|
*
|
||||||
* For now we use C++14 features.
|
* For now we use C++14 features.
|
||||||
*/
|
*/
|
||||||
if(m_gso.colored_face(m_aos, circ->face()))
|
if (m_gso.colored_face(m_aos, circ->face()))
|
||||||
{ m_gs.face_begin(m_gso.face_color(m_aos, circ->face())); }
|
m_gs.face_begin(m_gso.face_color(m_aos, circ->face()));
|
||||||
else
|
else
|
||||||
{ m_gs.face_begin(); }
|
m_gs.face_begin();
|
||||||
|
|
||||||
const auto* traits = this->m_aos.geometry_traits();
|
const auto* traits = this->m_aos.geometry_traits();
|
||||||
auto ext = find_smallest(circ, *traits);
|
auto ext = find_smallest(circ, *traits);
|
||||||
auto curr = ext;
|
auto curr = ext;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// Skip halfedges that are "antenas":
|
// Skip halfedges that are "antenas":
|
||||||
while (curr->face() == curr->twin()->face()) curr = curr->twin()->next();
|
while (curr->face() == curr->twin()->face()) curr = curr->twin()->next();
|
||||||
draw_region_impl1(curr, *traits, 0);
|
draw_region_impl1(curr, *traits, 0);
|
||||||
curr = curr->next();
|
curr = curr->next();
|
||||||
} while (curr != ext);
|
} while (curr != ext);
|
||||||
|
|
||||||
m_gs.face_end();
|
m_gs.face_end();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compile time dispatching
|
//! Compile time dispatching
|
||||||
#if 0
|
#if 0
|
||||||
template <typename T, typename I = void>
|
template <typename T, typename I = void>
|
||||||
void draw_region_impl2(Halfedge_const_handle curr, T const&, long)
|
void draw_region_impl2(Halfedge_const_handle curr, T const&, long)
|
||||||
{ draw_exact_region(curr); }
|
{ draw_exact_region(curr); }
|
||||||
|
|
||||||
template <typename T, typename I>
|
template <typename T, typename I>
|
||||||
auto draw_region_impl2(Halfedge_const_handle curr, T const& approx, int) ->
|
auto draw_region_impl2(Halfedge_const_handle curr, T const& approx, int) ->
|
||||||
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
|
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
|
||||||
bool{}), void())
|
bool{}), void())
|
||||||
{ draw_approximate_region(curr, approx); }
|
{ draw_approximate_region(curr, approx); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void draw_region_impl1(Halfedge_const_handle curr, T const&, long)
|
void draw_region_impl1(Halfedge_const_handle curr, T const&, long)
|
||||||
{ draw_exact_region(curr); }
|
{ draw_exact_region(curr); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto draw_region_impl1(Halfedge_const_handle curr, T const& traits, int) ->
|
auto draw_region_impl1(Halfedge_const_handle curr, T const& traits, int) ->
|
||||||
decltype(traits.approximate_2_object(), void()) {
|
decltype(traits.approximate_2_object(), void()) {
|
||||||
using Approximate = typename Gt::Approximate_2;
|
using Approximate = typename Gt::Approximate_2;
|
||||||
draw_region_impl2<Approximate, int>(curr, traits.approximate_2_object(), 0);
|
draw_region_impl2<Approximate, int>(curr, traits.approximate_2_object(), 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void draw_region_impl1(Halfedge_const_handle curr, T const& traits, int)
|
void draw_region_impl1(Halfedge_const_handle curr, T const& traits, int)
|
||||||
{ draw_approximate_region(curr, traits.approximate_2_object()); }
|
{ draw_approximate_region(curr, traits.approximate_2_object()); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Kernel_, int AtanX, int AtanY>
|
template <typename Kernel_, int AtanX, int AtanY>
|
||||||
void draw_region_impl1
|
void draw_region_impl1
|
||||||
(Halfedge_const_handle curr,
|
(Halfedge_const_handle curr,
|
||||||
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
||||||
int)
|
int)
|
||||||
{
|
{
|
||||||
if(!m_gso.draw_edge(m_aos, curr))
|
if (! m_gso.draw_edge(m_aos, curr)) return;
|
||||||
{ return; }
|
|
||||||
|
|
||||||
// std::cout << "draw_region_impl1()\n";
|
// std::cout << "draw_region_impl1()\n";
|
||||||
auto approx = traits.approximate_2_object();
|
auto approx = traits.approximate_2_object();
|
||||||
using Kernel = Kernel_;
|
using Kernel = Kernel_;
|
||||||
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>;
|
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>;
|
||||||
using Ak = typename Traits::Approximate_kernel;
|
using Ak = typename Traits::Approximate_kernel;
|
||||||
using Ap = typename Traits::Approximate_point_2;
|
using Ap = typename Traits::Approximate_point_2;
|
||||||
using Approx_point_3 = typename Ak::Point_3;
|
using Approx_point_3 = typename Ak::Point_3;
|
||||||
|
|
||||||
std::vector<Ap> polyline;
|
std::vector<Ap> polyline;
|
||||||
double error(0.01);
|
double error(0.01);
|
||||||
bool l2r = curr->direction() == ARR_LEFT_TO_RIGHT;
|
bool l2r = curr->direction() == ARR_LEFT_TO_RIGHT;
|
||||||
approx(curr->curve(), error, std::back_inserter(polyline), l2r);
|
approx(curr->curve(), error, std::back_inserter(polyline), l2r);
|
||||||
if (polyline.empty()) return;
|
if (polyline.empty()) return;
|
||||||
auto it = polyline.begin();
|
auto it = polyline.begin();
|
||||||
|
auto x = it->dx();
|
||||||
|
auto y = it->dy();
|
||||||
|
auto z = it->dz();
|
||||||
|
auto l = std::sqrt(x*x + y*y + z*z);
|
||||||
|
Approx_point_3 prev(x/l, y/l, z/l);
|
||||||
|
for (++it; it != polyline.end(); ++it) {
|
||||||
auto x = it->dx();
|
auto x = it->dx();
|
||||||
auto y = it->dy();
|
auto y = it->dy();
|
||||||
auto z = it->dz();
|
auto z = it->dz();
|
||||||
auto l = std::sqrt(x*x + y*y + z*z);
|
auto l = std::sqrt(x*x + y*y + z*z);
|
||||||
Approx_point_3 prev(x/l, y/l, z/l);
|
Approx_point_3 next(x/l, y/l, z/l);
|
||||||
for (++it; it != polyline.end(); ++it) {
|
|
||||||
auto x = it->dx();
|
|
||||||
auto y = it->dy();
|
|
||||||
auto z = it->dz();
|
|
||||||
auto l = std::sqrt(x*x + y*y + z*z);
|
|
||||||
Approx_point_3 next(x/l, y/l, z/l);
|
|
||||||
|
|
||||||
if(m_gso.colored_edge(m_aos, curr))
|
if (m_gso.colored_edge(m_aos, curr))
|
||||||
{ m_gs.add_segment(prev, next, m_gso.edge_color(m_aos, curr)); }
|
m_gs.add_segment(prev, next, m_gso.edge_color(m_aos, curr));
|
||||||
else
|
|
||||||
{ m_gs.add_segment(prev, next); }
|
|
||||||
|
|
||||||
prev = next;
|
|
||||||
// m_gs.add_point_in_face(*prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Draw a region using approximate coordinates.
|
|
||||||
* Call this member function only if the geometry traits is equipped with
|
|
||||||
* the coordinate-approximation functionality of a curve.
|
|
||||||
* This function must be inlined (e.g., a template) to enable the
|
|
||||||
* compiled-time dispatching in the function `draw_region()`.
|
|
||||||
*/
|
|
||||||
template <typename Approximate>
|
|
||||||
void draw_approximate_region(Halfedge_const_handle curr,
|
|
||||||
const Approximate& approx)
|
|
||||||
{
|
|
||||||
// std::cout << "draw_approximate_region()\n";
|
|
||||||
std::vector<typename Gt::Approximate_point_2> polyline;
|
|
||||||
double error(0.01); // TODO? (this->pixel_ratio());
|
|
||||||
bool l2r = curr->direction() == ARR_LEFT_TO_RIGHT;
|
|
||||||
approx(curr->curve(), error, std::back_inserter(polyline), l2r);
|
|
||||||
if (polyline.empty()) return;
|
|
||||||
auto it = polyline.begin();
|
|
||||||
auto prev = it++;
|
|
||||||
for (; it != polyline.end(); prev = it++) {
|
|
||||||
if(m_gso.draw_edge(m_aos, curr))
|
|
||||||
{
|
|
||||||
if(m_gso.colored_edge(m_aos, curr))
|
|
||||||
{ m_gs.add_segment(*prev, *it, m_gso.edge_color(m_aos, curr)); }
|
|
||||||
else
|
|
||||||
{ m_gs.add_segment(*prev, *it); }
|
|
||||||
}
|
|
||||||
m_gs.add_point_in_face(*prev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw an exact curve.
|
|
||||||
template <typename XMonotoneCurve>
|
|
||||||
void draw_exact_curve(const XMonotoneCurve& curve)
|
|
||||||
{
|
|
||||||
const auto* traits = this->m_aos.geometry_traits();
|
|
||||||
auto ctr_min = traits->construct_min_vertex_2_object();
|
|
||||||
auto ctr_max = traits->construct_max_vertex_2_object();
|
|
||||||
m_gs.add_segment(ctr_min(curve), ctr_max(curve));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Draw an exact region.
|
|
||||||
void draw_exact_region(Halfedge_const_handle curr)
|
|
||||||
{
|
|
||||||
// this->add_point_in_face(curr->source()->point());
|
|
||||||
draw_exact_curve(curr->curve());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add all faces.
|
|
||||||
template <typename Traits>
|
|
||||||
void add_faces(const Traits&)
|
|
||||||
{
|
|
||||||
for (auto it=m_aos.unbounded_faces_begin(); it!=m_aos.unbounded_faces_end(); ++it)
|
|
||||||
{ add_face(it); }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add all faces.
|
|
||||||
template <typename Kernel_, int AtanX, int AtanY>
|
|
||||||
void add_faces(Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const&)
|
|
||||||
{ add_face(m_aos.faces_begin()); }
|
|
||||||
|
|
||||||
/// Compile time dispatching
|
|
||||||
#if 0
|
|
||||||
template <typename T>
|
|
||||||
void draw_point_impl2(const Point& p, T const&, long) { m_gs.add_point(p); }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
auto draw_point_impl2(const Point& p, T const& approx, int) ->
|
|
||||||
decltype(approx.operator()(p), void())
|
|
||||||
{ m_gs.add_point(approx(p)); }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
void draw_point_impl1(const Point& p, T const&, long) { m_gs.add_point(p); }
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
auto draw_point_impl1(const Point& p, T const& traits, int) ->
|
|
||||||
decltype(traits.approximate_2_object(), void()) {
|
|
||||||
using Approximate = typename Gt::Approximate_2;
|
|
||||||
draw_point_impl2<Approximate>(p, traits.approximate_2_object(), true);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
template <typename T>
|
|
||||||
void draw_point_impl1(const Point& p, T const& traits, int,
|
|
||||||
bool colored, const CGAL::IO::Color& color)
|
|
||||||
{
|
|
||||||
if(colored)
|
|
||||||
{ m_gs.add_point(traits.approximate_2_object()(p), color); }
|
|
||||||
else
|
else
|
||||||
{ m_gs.add_point(traits.approximate_2_object()(p)); }
|
m_gs.add_segment(prev, next);
|
||||||
|
|
||||||
|
prev = next;
|
||||||
|
// m_gs.add_point_in_face(*prev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! draws a region using approximate coordinates.
|
||||||
|
* Call this member function only if the geometry traits is equipped with
|
||||||
|
* the coordinate-approximation functionality of a curve.
|
||||||
|
* This function must be inlined (e.g., a template) to enable the
|
||||||
|
* compiled-time dispatching in the function `draw_region()`.
|
||||||
|
*/
|
||||||
|
template <typename Approximate>
|
||||||
|
void draw_approximate_region(Halfedge_const_handle curr,
|
||||||
|
const Approximate& approx) {
|
||||||
|
// std::cout << "draw_approximate_region()\n";
|
||||||
|
std::vector<typename Gt::Approximate_point_2> polyline;
|
||||||
|
double error(0.01); // TODO? (this->pixel_ratio());
|
||||||
|
bool l2r = curr->direction() == ARR_LEFT_TO_RIGHT;
|
||||||
|
approx(curr->curve(), error, std::back_inserter(polyline), l2r);
|
||||||
|
if (polyline.empty()) return;
|
||||||
|
auto it = polyline.begin();
|
||||||
|
auto prev = it++;
|
||||||
|
for (; it != polyline.end(); prev = it++) {
|
||||||
|
if (m_gso.draw_edge(m_aos, curr)) {
|
||||||
|
if (m_gso.colored_edge(m_aos, curr))
|
||||||
|
m_gs.add_segment(*prev, *it, m_gso.edge_color(m_aos, curr));
|
||||||
|
else
|
||||||
|
m_gs.add_segment(*prev, *it);
|
||||||
|
}
|
||||||
|
m_gs.add_point_in_face(*prev);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws an exact curve.
|
||||||
|
template <typename XMonotoneCurve>
|
||||||
|
void draw_exact_curve(const XMonotoneCurve& curve) {
|
||||||
|
const auto* traits = this->m_aos.geometry_traits();
|
||||||
|
auto ctr_min = traits->construct_min_vertex_2_object();
|
||||||
|
auto ctr_max = traits->construct_max_vertex_2_object();
|
||||||
|
m_gs.add_segment(ctr_min(curve), ctr_max(curve));
|
||||||
|
}
|
||||||
|
|
||||||
|
//! draws an exact region.
|
||||||
|
void draw_exact_region(Halfedge_const_handle curr) {
|
||||||
|
// this->add_point_in_face(curr->source()->point());
|
||||||
|
draw_exact_curve(curr->curve());
|
||||||
|
}
|
||||||
|
|
||||||
|
//! adds all faces.
|
||||||
|
template <typename Traits>
|
||||||
|
void add_faces(const Traits&) {
|
||||||
|
for (auto it = m_aos.unbounded_faces_begin(); it != m_aos.unbounded_faces_end(); ++it)
|
||||||
|
add_face(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! adds all faces.
|
||||||
|
template <typename Kernel_, int AtanX, int AtanY>
|
||||||
|
void add_faces(Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const&)
|
||||||
|
{ add_face(m_aos.faces_begin()); }
|
||||||
|
|
||||||
|
//! Compile time dispatching
|
||||||
|
#if 0
|
||||||
|
template <typename T>
|
||||||
|
void draw_point_impl2(const Point& p, T const&, long) { m_gs.add_point(p); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto draw_point_impl2(const Point& p, T const& approx, int) ->
|
||||||
|
decltype(approx.operator()(p), void())
|
||||||
|
{ m_gs.add_point(approx(p)); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void draw_point_impl1(const Point& p, T const&, long) { m_gs.add_point(p); }
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
auto draw_point_impl1(const Point& p, T const& traits, int) ->
|
||||||
|
decltype(traits.approximate_2_object(), void()) {
|
||||||
|
using Approximate = typename Gt::Approximate_2;
|
||||||
|
draw_point_impl2<Approximate>(p, traits.approximate_2_object(), true);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
template <typename T>
|
||||||
|
void draw_point_impl1(const Point& p, T const& traits, int,
|
||||||
|
bool colored, const CGAL::IO::Color& color) {
|
||||||
|
if (colored)
|
||||||
|
{ m_gs.add_point(traits.approximate_2_object()(p), color); }
|
||||||
|
else
|
||||||
|
{ m_gs.add_point(traits.approximate_2_object()(p)); }
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Kernel_, int AtanX, int AtanY>
|
template <typename Kernel_, int AtanX, int AtanY>
|
||||||
void draw_point_impl1
|
void draw_point_impl1
|
||||||
(const Point& p,
|
(const Point& p,
|
||||||
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
||||||
int,
|
int,
|
||||||
bool colored,
|
bool colored,
|
||||||
const CGAL::IO::Color& color)
|
const CGAL::IO::Color& color) {
|
||||||
{
|
auto approx = traits.approximate_2_object();
|
||||||
auto approx = traits.approximate_2_object();
|
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>;
|
||||||
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY>;
|
using Ak = typename Traits::Approximate_kernel;
|
||||||
using Ak = typename Traits::Approximate_kernel;
|
using Approx_point_3 = typename Ak::Point_3;
|
||||||
using Approx_point_3 = typename Ak::Point_3;
|
auto ap = approx(p);
|
||||||
auto ap = approx(p);
|
auto x = ap.dx();
|
||||||
auto x = ap.dx();
|
auto y = ap.dy();
|
||||||
auto y = ap.dy();
|
auto z = ap.dz();
|
||||||
auto z = ap.dz();
|
auto l = std::sqrt(x*x + y*y + z*z);
|
||||||
auto l = std::sqrt(x*x + y*y + z*z);
|
Approx_point_3 p3(x/l, y/l, z/l);
|
||||||
Approx_point_3 p3(x/l, y/l, z/l);
|
if (colored) m_gs.add_point(p3, color);
|
||||||
if(colored)
|
else m_gs.add_point(p3);
|
||||||
{ m_gs.add_point(p3, color); }
|
}
|
||||||
|
|
||||||
|
//! draws a point.
|
||||||
|
void draw_point(Vertex_const_handle vh) {
|
||||||
|
const auto* traits = m_aos.geometry_traits();
|
||||||
|
if (m_gso.draw_vertex(m_aos, vh)) {
|
||||||
|
if (m_gso.colored_vertex(m_aos, vh))
|
||||||
|
draw_point_impl1(vh->point(), *traits, 0, true,
|
||||||
|
m_gso.vertex_color(m_aos, vh));
|
||||||
else
|
else
|
||||||
{ m_gs.add_point(p3); }
|
draw_point_impl1(vh->point(), *traits, 0, false, CGAL::IO::Color()); // color will be unused
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Draw a point.
|
template <typename Kernel, int AtanX, int AtanY>
|
||||||
void draw_point(Vertex_const_handle vh)
|
Halfedge_const_handle
|
||||||
{
|
find_smallest(Ccb_halfedge_const_circulator circ,
|
||||||
const auto* traits = m_aos.geometry_traits();
|
Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY> const&)
|
||||||
if(m_gso.draw_vertex(m_aos, vh))
|
{ return circ; }
|
||||||
{
|
|
||||||
if(m_gso.colored_vertex(m_aos, vh))
|
/*! finds the halfedge incident to the lexicographically smallest vertex
|
||||||
{ draw_point_impl1(vh->point(), *traits, 0, true,
|
* along the CCB, such that there is no other halfedge underneath.
|
||||||
m_gso.vertex_color(m_aos, vh)); }
|
*/
|
||||||
else
|
template <typename Traits>
|
||||||
{ draw_point_impl1(vh->point(), *traits, 0, false, CGAL::IO::Color()); } // color will be unused
|
Halfedge_const_handle find_smallest(Ccb_halfedge_const_circulator circ,
|
||||||
|
const Traits&) {
|
||||||
|
// std::cout << "find_smallest()\n";
|
||||||
|
const auto* traits = this->m_aos.geometry_traits();
|
||||||
|
auto cmp_xy = traits->compare_xy_2_object();
|
||||||
|
auto cmp_y = traits->compare_y_at_x_right_2_object();
|
||||||
|
|
||||||
|
// Find the first halfedge directed from left to right
|
||||||
|
auto curr = circ;
|
||||||
|
do if (curr->direction() == CGAL::ARR_LEFT_TO_RIGHT) break;
|
||||||
|
while (++curr != circ);
|
||||||
|
Halfedge_const_handle ext = curr;
|
||||||
|
|
||||||
|
// Find the halfedge incident to the lexicographically smallest vertex,
|
||||||
|
// such that there is no other halfedge underneath.
|
||||||
|
do {
|
||||||
|
// Discard edges not directed from left to right:
|
||||||
|
if (curr->direction() != CGAL::ARR_LEFT_TO_RIGHT) continue;
|
||||||
|
|
||||||
|
auto res = cmp_xy(curr->source()->point(), ext->source()->point());
|
||||||
|
|
||||||
|
// Discard the edges inciden to a point strictly larger than the point
|
||||||
|
// incident to the stored extreme halfedge:
|
||||||
|
if (res == LARGER) continue;
|
||||||
|
|
||||||
|
// Store the edge inciden to a point strictly smaller:
|
||||||
|
if (res == SMALLER) {
|
||||||
|
ext = curr;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Kernel, int AtanX, int AtanY>
|
// The incident points are equal; compare the halfedges themselves:
|
||||||
Halfedge_const_handle
|
if (cmp_y(curr->curve(), ext->curve(), curr->source()->point()) ==
|
||||||
find_smallest(Ccb_halfedge_const_circulator circ,
|
SMALLER)
|
||||||
Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY> const&)
|
ext = curr;
|
||||||
{ return circ; }
|
} while (++curr != circ);
|
||||||
|
|
||||||
/*! Find the halfedge incident to the lexicographically smallest vertex
|
return ext;
|
||||||
* along the CCB, such that there is no other halfedge underneath.
|
}
|
||||||
*/
|
|
||||||
template <typename Traits>
|
|
||||||
Halfedge_const_handle find_smallest(Ccb_halfedge_const_circulator circ,
|
|
||||||
const Traits&)
|
|
||||||
{
|
|
||||||
// std::cout << "find_smallest()\n";
|
|
||||||
const auto* traits = this->m_aos.geometry_traits();
|
|
||||||
auto cmp_xy = traits->compare_xy_2_object();
|
|
||||||
auto cmp_y = traits->compare_y_at_x_right_2_object();
|
|
||||||
|
|
||||||
// Find the first halfedge directed from left to right
|
//! adds all elements to be drawn.
|
||||||
auto curr = circ;
|
void add_elements() {
|
||||||
do if (curr->direction() == CGAL::ARR_LEFT_TO_RIGHT) break;
|
|
||||||
while (++curr != circ);
|
|
||||||
Halfedge_const_handle ext = curr;
|
|
||||||
|
|
||||||
// Find the halfedge incident to the lexicographically smallest vertex,
|
|
||||||
// such that there is no other halfedge underneath.
|
|
||||||
do {
|
|
||||||
// Discard edges not directed from left to right:
|
|
||||||
if (curr->direction() != CGAL::ARR_LEFT_TO_RIGHT) continue;
|
|
||||||
|
|
||||||
auto res = cmp_xy(curr->source()->point(), ext->source()->point());
|
|
||||||
|
|
||||||
// Discard the edges inciden to a point strictly larger than the point
|
|
||||||
// incident to the stored extreme halfedge:
|
|
||||||
if (res == LARGER) continue;
|
|
||||||
|
|
||||||
// Store the edge inciden to a point strictly smaller:
|
|
||||||
if (res == SMALLER) {
|
|
||||||
ext = curr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The incident points are equal; compare the halfedges themselves:
|
|
||||||
if (cmp_y(curr->curve(), ext->curve(), curr->source()->point()) ==
|
|
||||||
SMALLER)
|
|
||||||
ext = curr;
|
|
||||||
} while (++curr != circ);
|
|
||||||
|
|
||||||
return ext;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Add all elements to be drawn.
|
|
||||||
void add_elements()
|
|
||||||
{
|
|
||||||
// std::cout << "add_elements()\n";
|
// std::cout << "add_elements()\n";
|
||||||
// std::cout << "ratio: " << this->pixel_ratio() << std::endl;
|
// std::cout << "ratio: " << this->pixel_ratio() << std::endl;
|
||||||
m_visited.clear();
|
m_visited.clear();
|
||||||
|
|
||||||
if (m_aos.is_empty()) return;
|
if (m_aos.is_empty()) return;
|
||||||
|
|
||||||
if(m_gso.are_faces_enabled())
|
if (m_gso.are_faces_enabled())
|
||||||
{ add_faces(*(this->m_aos.geometry_traits())); }
|
{ add_faces(*(this->m_aos.geometry_traits())); }
|
||||||
|
|
||||||
// Add edges that do not separate faces.
|
// Add edges that do not separate faces.
|
||||||
if(m_gso.are_edges_enabled())
|
if (m_gso.are_edges_enabled()) {
|
||||||
{
|
for (auto it = m_aos.edges_begin(); it != m_aos.edges_end(); ++it) {
|
||||||
for (auto it = m_aos.edges_begin(); it != m_aos.edges_end(); ++it)
|
if (it->face()==it->twin()->face()) {
|
||||||
{ if (it->face()==it->twin()->face())
|
if (m_gso.draw_edge(m_aos, it)) {
|
||||||
{
|
if (m_gso.colored_edge(m_aos, it))
|
||||||
if(m_gso.draw_edge(m_aos, it))
|
draw_curve(it->curve(), true, m_gso.edge_color(m_aos, it));
|
||||||
{
|
|
||||||
if(m_gso.colored_edge(m_aos, it))
|
|
||||||
{ draw_curve(it->curve(), true, m_gso.edge_color(m_aos, it)); }
|
|
||||||
else
|
else
|
||||||
{ draw_curve(it->curve(), false, CGAL::IO::Color()); }
|
draw_curve(it->curve(), false, CGAL::IO::Color());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add all points
|
// Add all points
|
||||||
if(m_gso.are_vertices_enabled())
|
if (m_gso.are_vertices_enabled()) {
|
||||||
{
|
|
||||||
for (auto it = m_aos.vertices_begin(); it != m_aos.vertices_end(); ++it)
|
for (auto it = m_aos.vertices_begin(); it != m_aos.vertices_end(); ++it)
|
||||||
{ draw_point(it); }
|
draw_point(it);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_visited.clear();
|
m_visited.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Draw a curve using approximate coordinates.
|
/*! draws a curve using approximate coordinates.
|
||||||
* Call this member function only of the geometry traits is equipped with
|
* Call this member function only of the geometry traits is equipped with
|
||||||
* the coordinate-aproximation functionality of a curve.
|
* the coordinate-aproximation functionality of a curve.
|
||||||
* This function must be inlined (e.g., a template) to enable the
|
* This function must be inlined (e.g., a template) to enable the
|
||||||
|
|
@ -425,149 +404,138 @@ namespace draw_function_for_arrangement_2
|
||||||
template <typename XMonotoneCurve, typename Approximate>
|
template <typename XMonotoneCurve, typename Approximate>
|
||||||
void draw_approximate_curve(const XMonotoneCurve& curve,
|
void draw_approximate_curve(const XMonotoneCurve& curve,
|
||||||
const Approximate& approx,
|
const Approximate& approx,
|
||||||
bool colored, const CGAL::IO::Color& c)
|
bool colored, const CGAL::IO::Color& c) {
|
||||||
{
|
|
||||||
std::vector<typename Gt::Approximate_point_2> polyline;
|
std::vector<typename Gt::Approximate_point_2> polyline;
|
||||||
double error(0.01); // TODO? (this->pixel_ratio());
|
double error(0.01); // TODO? (this->pixel_ratio());
|
||||||
approx(curve, error, std::back_inserter(polyline));
|
approx(curve, error, std::back_inserter(polyline));
|
||||||
if (polyline.empty()) return;
|
if (polyline.empty()) return;
|
||||||
auto it = polyline.begin();
|
auto it = polyline.begin();
|
||||||
auto prev = it++;
|
auto prev = it++;
|
||||||
for (; it != polyline.end(); prev = it++)
|
for (; it != polyline.end(); prev = it++) {
|
||||||
{
|
if (colored) m_gs.add_segment(*prev, *it, c);
|
||||||
if(colored)
|
else m_gs.add_segment(*prev, *it);
|
||||||
{ m_gs.add_segment(*prev, *it, c); }
|
|
||||||
else
|
|
||||||
{ m_gs.add_segment(*prev, *it); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! Compile time dispatching
|
/*! Compile time dispatching
|
||||||
*/
|
*/
|
||||||
#if 0
|
#if 0
|
||||||
template <typename T, typename I = void>
|
template <typename T, typename I = void>
|
||||||
void draw_curve_impl2(const X_monotone_curve& xcv, T const&, long)
|
void draw_curve_impl2(const X_monotone_curve& xcv, T const&, long)
|
||||||
{ draw_exact_curve(xcv); }
|
{ draw_exact_curve(xcv); }
|
||||||
|
|
||||||
template <typename T, typename I>
|
template <typename T, typename I>
|
||||||
auto draw_curve_impl2(const X_monotone_curve& xcv, T const& approx, int) ->
|
auto draw_curve_impl2(const X_monotone_curve& xcv, T const& approx, int) ->
|
||||||
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
|
decltype(approx.template operator()<I>(X_monotone_curve{}, double{}, I{},
|
||||||
bool{}), void())
|
bool{}), void())
|
||||||
{ draw_approximate_curve(xcv, approx); }
|
{ draw_approximate_curve(xcv, approx); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void draw_curve_impl1(const X_monotone_curve& xcv, T const&, long)
|
void draw_curve_impl1(const X_monotone_curve& xcv, T const&, long)
|
||||||
{ draw_exact_curve(xcv); }
|
{ draw_exact_curve(xcv); }
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
auto draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int) ->
|
auto draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int) ->
|
||||||
decltype(traits.approximate_2_object(), void()) {
|
decltype(traits.approximate_2_object(), void()) {
|
||||||
using Approximate = typename Gt::Approximate_2;
|
using Approximate = typename Gt::Approximate_2;
|
||||||
draw_curve_impl2<Approximate, int>(xcv, traits.approximate_2_object(), 0);
|
draw_curve_impl2<Approximate, int>(xcv, traits.approximate_2_object(), 0);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int,
|
void draw_curve_impl1(const X_monotone_curve& xcv, T const& traits, int,
|
||||||
bool colored, const CGAL::IO::Color& c)
|
bool colored, const CGAL::IO::Color& c)
|
||||||
{ draw_approximate_curve(xcv, traits.approximate_2_object(), colored, c); }
|
{ draw_approximate_curve(xcv, traits.approximate_2_object(), colored, c); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template <typename Kernel_, int AtanX, int AtanY>
|
template <typename Kernel_, int AtanX, int AtanY>
|
||||||
void draw_curve_impl1
|
void draw_curve_impl1
|
||||||
(const X_monotone_curve& xcv,
|
(const X_monotone_curve& xcv,
|
||||||
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
Arr_geodesic_arc_on_sphere_traits_2<Kernel_, AtanX, AtanY> const& traits,
|
||||||
int,
|
int,
|
||||||
bool colored, const CGAL::IO::Color& c)
|
bool colored, const CGAL::IO::Color& c)
|
||||||
{
|
{
|
||||||
auto approx = traits.approximate_2_object();
|
auto approx = traits.approximate_2_object();
|
||||||
using Kernel = Kernel_;
|
using Kernel = Kernel_;
|
||||||
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>;
|
using Traits = Arr_geodesic_arc_on_sphere_traits_2<Kernel, AtanX, AtanY>;
|
||||||
using Ak = typename Traits::Approximate_kernel;
|
using Ak = typename Traits::Approximate_kernel;
|
||||||
using Ap = typename Traits::Approximate_point_2;
|
using Ap = typename Traits::Approximate_point_2;
|
||||||
using Approx_point_3 = typename Ak::Point_3;
|
using Approx_point_3 = typename Ak::Point_3;
|
||||||
std::vector<Ap> apoints;
|
std::vector<Ap> apoints;
|
||||||
double error(0.01);
|
double error(0.01);
|
||||||
approx(xcv, error, std::back_inserter(apoints));
|
approx(xcv, error, std::back_inserter(apoints));
|
||||||
auto it = apoints.begin();
|
auto it = apoints.begin();
|
||||||
|
auto x = it->dx();
|
||||||
|
auto y = it->dy();
|
||||||
|
auto z = it->dz();
|
||||||
|
auto l = std::sqrt(x*x + y*y + z*z);
|
||||||
|
Approx_point_3 prev(x/l, y/l, z/l);
|
||||||
|
for (++it; it != apoints.end(); ++it) {
|
||||||
auto x = it->dx();
|
auto x = it->dx();
|
||||||
auto y = it->dy();
|
auto y = it->dy();
|
||||||
auto z = it->dz();
|
auto z = it->dz();
|
||||||
auto l = std::sqrt(x*x + y*y + z*z);
|
auto l = std::sqrt(x*x + y*y + z*z);
|
||||||
Approx_point_3 prev(x/l, y/l, z/l);
|
Approx_point_3 next(x/l, y/l, z/l);
|
||||||
for (++it; it != apoints.end(); ++it) {
|
if (colored) m_gs.add_segment(prev, next, c);
|
||||||
auto x = it->dx();
|
else m_gs.add_segment(prev, next);
|
||||||
auto y = it->dy();
|
prev = next;
|
||||||
auto z = it->dz();
|
|
||||||
auto l = std::sqrt(x*x + y*y + z*z);
|
|
||||||
Approx_point_3 next(x/l, y/l, z/l);
|
|
||||||
if(colored)
|
|
||||||
{ m_gs.add_segment(prev, next, c); }
|
|
||||||
else
|
|
||||||
{ m_gs.add_segment(prev, next); }
|
|
||||||
prev = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Draw a curve.
|
//! draws a curve.
|
||||||
template <typename XMonotoneCurve>
|
template <typename XMonotoneCurve>
|
||||||
void draw_curve(const XMonotoneCurve& curve,
|
void draw_curve(const XMonotoneCurve& curve,
|
||||||
bool colored, const CGAL::IO::Color& c)
|
bool colored, const CGAL::IO::Color& c) {
|
||||||
{
|
/* Check whether the traits has a member function called
|
||||||
/* Check whether the traits has a member function called
|
* approximate_2_object() and if so check whether the return type, namely
|
||||||
* approximate_2_object() and if so check whether the return type, namely
|
* `Approximate_2` has an appropriate operator.
|
||||||
* `Approximate_2` has an appropriate operator.
|
*
|
||||||
*
|
* C++20 supports concepts and `requires` expression; see, e.g.,
|
||||||
* C++20 supports concepts and `requires` expression; see, e.g.,
|
* https://en.cppreference.com/w/cpp/language/constraints; thus, the first
|
||||||
* https://en.cppreference.com/w/cpp/language/constraints; thus, the first
|
* condition above can be elegantly verified as follows:
|
||||||
* condition above can be elegantly verified as follows:
|
* constexpr bool has_approximate_2_object =
|
||||||
* constexpr bool has_approximate_2_object =
|
* requires(const Gt& traits) { traits.approximate_2_object(); };
|
||||||
* requires(const Gt& traits) { traits.approximate_2_object(); };
|
*
|
||||||
*
|
* C++17 has experimental constructs called is_detected and
|
||||||
* C++17 has experimental constructs called is_detected and
|
* is_detected_v that can be used to achieve the same goal.
|
||||||
* is_detected_v that can be used to achieve the same goal.
|
*
|
||||||
*
|
* For now we use C++14 features.
|
||||||
* For now we use C++14 features.
|
*/
|
||||||
*/
|
|
||||||
#if 0
|
#if 0
|
||||||
if constexpr (std::experimental::is_detected_v<approximate_2_object_t, Gt>)
|
if constexpr (std::experimental::is_detected_v<approximate_2_object_t, Gt>) {
|
||||||
{
|
|
||||||
const auto* traits = this->m_aos.geometry_traits();
|
|
||||||
auto approx = traits->approximate_2_object();
|
|
||||||
draw_approximate_curve(curve, approx);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
draw_exact_curve(curve);
|
|
||||||
#else
|
|
||||||
const auto* traits = this->m_aos.geometry_traits();
|
const auto* traits = this->m_aos.geometry_traits();
|
||||||
draw_curve_impl1(curve, *traits, 0, colored, c);
|
auto approx = traits->approximate_2_object();
|
||||||
#endif
|
draw_approximate_curve(curve, approx);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
draw_exact_curve(curve);
|
||||||
|
#else
|
||||||
|
const auto* traits = this->m_aos.geometry_traits();
|
||||||
|
draw_curve_impl1(curve, *traits, 0, colored, c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Arr& m_aos;
|
Arr& m_aos;
|
||||||
CGAL::Graphics_scene& m_gs;
|
CGAL::Graphics_scene& m_gs;
|
||||||
const GSOptions& m_gso;
|
const GSOptions& m_gso;
|
||||||
std::unordered_map<Face_const_handle, bool> m_visited;
|
std::unordered_map<Face_const_handle, bool> m_visited;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace draw_function_for_arrangement_2
|
} // namespace draw_aos
|
||||||
|
|
||||||
#define CGAL_ARR_TYPE CGAL::Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>
|
#define CGAL_ARR_TYPE CGAL::Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>
|
||||||
|
|
||||||
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
|
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
|
||||||
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
|
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
|
||||||
CGAL::Graphics_scene& graphics_scene,
|
CGAL::Graphics_scene& graphics_scene,
|
||||||
const GSOptions& gso)
|
const GSOptions& gso) {
|
||||||
{
|
draw_aos::Draw_arr_tool dar(aos, graphics_scene, gso);
|
||||||
draw_function_for_arrangement_2::Draw_arr_tool dar(aos, graphics_scene, gso);
|
|
||||||
dar.add_elements();
|
dar.add_elements();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename GeometryTraits_2, typename TopologyTraits>
|
template <typename GeometryTraits_2, typename TopologyTraits>
|
||||||
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
|
void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
|
||||||
CGAL::Graphics_scene& graphics_scene)
|
CGAL::Graphics_scene& graphics_scene) {
|
||||||
{
|
|
||||||
CGAL::Graphics_scene_options<CGAL_ARR_TYPE,
|
CGAL::Graphics_scene_options<CGAL_ARR_TYPE,
|
||||||
typename CGAL_ARR_TYPE::Vertex_const_handle,
|
typename CGAL_ARR_TYPE::Vertex_const_handle,
|
||||||
typename CGAL_ARR_TYPE::Halfedge_const_handle,
|
typename CGAL_ARR_TYPE::Halfedge_const_handle,
|
||||||
|
|
@ -587,11 +555,10 @@ void add_to_graphics_scene(const CGAL_ARR_TYPE& aos,
|
||||||
add_to_graphics_scene(aos, graphics_scene, gso);
|
add_to_graphics_scene(aos, graphics_scene, gso);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draw an arrangement on surface.
|
//! draws an arrangement on surface.
|
||||||
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
|
template <typename GeometryTraits_2, typename TopologyTraits, class GSOptions>
|
||||||
void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso,
|
void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso,
|
||||||
const char* title = "2D Arrangement on Surface Basic Viewer")
|
const char* title = "2D Arrangement on Surface Basic Viewer") {
|
||||||
{
|
|
||||||
CGAL::Graphics_scene graphics_scene;
|
CGAL::Graphics_scene graphics_scene;
|
||||||
add_to_graphics_scene(aos, graphics_scene, gso);
|
add_to_graphics_scene(aos, graphics_scene, gso);
|
||||||
draw_graphics_scene(graphics_scene, title);
|
draw_graphics_scene(graphics_scene, title);
|
||||||
|
|
@ -600,8 +567,7 @@ void draw(const CGAL_ARR_TYPE& aos, const GSOptions& gso,
|
||||||
|
|
||||||
template <typename GeometryTraits_2, typename TopologyTraits>
|
template <typename GeometryTraits_2, typename TopologyTraits>
|
||||||
void draw(const CGAL_ARR_TYPE& aos,
|
void draw(const CGAL_ARR_TYPE& aos,
|
||||||
const char* title = "2D Arrangement on Surface Basic Viewer")
|
const char* title = "2D Arrangement on Surface Basic Viewer") {
|
||||||
{
|
|
||||||
CGAL::Graphics_scene graphics_scene;
|
CGAL::Graphics_scene graphics_scene;
|
||||||
add_to_graphics_scene(aos, graphics_scene);
|
add_to_graphics_scene(aos, graphics_scene);
|
||||||
draw_graphics_scene(graphics_scene, title);
|
draw_graphics_scene(graphics_scene, title);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,12 @@
|
||||||
|
|
||||||
Release date: July 2026
|
Release date: July 2026
|
||||||
|
|
||||||
|
### [2D Arrangements](https://doc.cgal.org/6.1/Manual/packages.html#PkgArrangementOnSurface2)
|
||||||
|
|
||||||
|
- Introduced a Geometry Traits concept for arrangement on surfaces that enables the provision of the disconnected portions of an approximation of a curve within a given bounding box.
|
||||||
|
- Made the `Arr_linear_traits_2` a model of the new concept.
|
||||||
|
|
||||||
|
|
||||||
### [Linear Cell Complex](https://doc.cgal.org/6.2/Manual/packages.html#PkgLinearCellComplex)
|
### [Linear Cell Complex](https://doc.cgal.org/6.2/Manual/packages.html#PkgLinearCellComplex)
|
||||||
|
|
||||||
- **API Changes**: The following import functions have been deprecated and renamed for better naming clarity and consistency:
|
- **API Changes**: The following import functions have been deprecated and renamed for better naming clarity and consistency:
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue