namespace CGAL { /*! \ingroup PkgNefS2Ref An instance of data type `Nef_polyhedron_S2` is a subset of the sphere \f$ S_2\f$ that is the result of forming complements and intersections starting from a finite set `H` of halfspaces bounded by a plane containing the origin. Halfspaces correspond to hemispheres of \f$ S_2\f$ and are therefore modeled by oriented great circles of type `Sphere_circle`. `Nef_polyhedron_S2` is closed under all binary set operations `intersection`, `union`, `difference`, `complement` and under the topological operations `boundary`, `closure`, and `interior`. \cgalHeading{Parameters} \code template< class Nef_polyhedronTraits_S2, class Nef_polyhedronItems_S2 = CGAL::SM_items, class Nef_polyhedronMarks = bool > class Nef_polyhedron_S2; \endcode The first parameter requires one of the following exact kernels: `Homogeneous`, `Simple_homogeneous` parametrized with `Gmpz`, `leda_integer` or any other number type modeling \f$\mathbb{Z}\f$, or `Cartesian`, `Simple_cartesian` parametrized with `Gmpq`, `leda_rational`, `Quotient` or any other number type modeling \f$\mathbb{Q}\f$. The second parameter and the third parameter are for future considerations. Neither `Nef_polyhedronItems_S2` nor `Nef_polyhedronMarks` is specifed, yet. Do not use other than the default types for these two template parameters. \cgalHeading{Exploration - Point location - Ray shooting} As Nef polyhedra are the result of forming complements and intersections starting from a set `H` of half-spaces that are defined by oriented lines in the plane, they can be represented by an attributed plane map \f$ M = (V,E,F)\f$. For topological queries within `M` the following types and operations allow exploration access to this structure. \cgalHeading{Input and Output} A Nef polyhedron `N` can be visualized in an open GL window. The output operator is defined in the file `CGAL/IO/Nef_polyhedron_2_Window-stream.h`. \cgalHeading{Implementation} Nef polyhedra are implemented on top of a halfedge data structure and use linear space in the number of vertices, edges and facets. Operations like `empty` take constant time. The operations `clear`, `complement`, `interior`, `closure`, `boundary`, `regularization`, input and output take linear time. All binary set operations and comparison operations take time \f$ O(n \log n)\f$ where \f$ n\f$ is the size of the output plus the size of the input. The point location and ray shooting operations are implemented in the naive way. The operations run in linear query time without any preprocessing. */ template< typename Traits > class Nef_polyhedron_S2 { public: /// \name Types /// @{ /*! \ingroup PkgNefS2Ref An object `c` of type `Sphere_circle` is an oriented great circle on the surface of a unit sphere. Such circles correspond to the intersection of an oriented plane (that contains the origin) and the surface of \f$ S_2\f$. The orientation of the great circle is that of a counterclockwise walk along the circle as seen from the positive halfspace of the oriented plane. */ class Sphere_circle { public: /// \name Types /// @{ /*! ring type. */ typedef unspecified_type RT; /*! plane a `Sphere_circle` lies in. */ typedef unspecified_type Plane_3; /// @} /// \name Creation /// @{ /*! creates some great circle. */ Sphere_circle(); /*! If \f$ p\f$ and \f$ q\f$ are opposite of each other, then we create the unique great circle on \f$ S_2\f$ which contains p and q. This circle is oriented such that a walk along `c` meets \f$ p\f$ just before the shorter segment between \f$ p\f$ and \f$ q\f$. If \f$ p\f$ and \f$ q\f$ are opposite of each other then we create any great circle that contains \f$ p\f$ and \f$ q\f$. */ Sphere_circle(const Sphere_point& p, const Sphere_point& q); /*! creates the circle corresponding to the plane `h`. \pre `h` contains the origin. */ Sphere_circle(const Plane_3& h); /*! creates the circle orthogonal to the vector \f$ (x,y,z)\f$. */ Sphere_circle(const RT& x, const RT& y, const RT& z); /*! creates a great circle orthogonal to \f$ c\f$ that contains \f$ p\f$. \pre \f$ p\f$ is not part of \f$ c\f$. */ Sphere_circle(Sphere_circle c, const Sphere_point& p); /// @} /// \name Operations /// @{ /*! Returns a sphere circle in the opposite direction of `c`. */ Sphere_circle opposite() ; /*! returns true iff `c` contains `p`. */ bool has_on(const Sphere_point& p) ; /*! returns the plane supporting `c`. */ Plane_3 plane() ; /*! returns the point that is the pole of the hemisphere left of `c`. */ Sphere_point orthogonal_pole() ; /// @} }; /* end Sphere_circle */ /*! \ingroup PkgNefS2Ref An object `p` of type `Sphere_point` is a point on the surface of a unit sphere. Such points correspond to the nontrivial directions in space and similarly to the equivalence classes of all nontrivial vectors under normalization. \cgalHeading{Operations} Access to the coordinates is provided by the following operations. Note that the vector \f$ (x,y,z)\f$ is not normalized. */ class Sphere_point { public: /// \name Types /// @{ /*! ring number type. */ typedef unspecified_type RT; /// @} /// \name Creation /// @{ /*! creates some sphere point. */ Sphere_point(); /*! creates a sphere point corresponding to the point of intersection of the ray starting at the origin in direction \f$ (x,y,z)\f$ and the surface of \f$ S_2\f$. */ Sphere_point(RT x, RT y, RT z); /// @} /// \name Operations /// @{ /*! the \f$ x\f$-coordinate. */ RT x() ; /*! the \f$ y\f$-coordinate. */ RT y() ; /*! the \f$ z\f$-coordinate. */ RT z() ; /*! Equality. */ bool operator==(const Nef_polyhedron_S2::Sphere_point& q) ; /*! Inequality. */ bool operator!=(const Nef_polyhedron_S2::Sphere_point& q) ; /*! returns the antipode of `p`. */ Sphere_point antipode() ; /// @} }; /* end Sphere_point */ /*! \ingroup PkgNefS2Ref An object `s` of type `Sphere_segment` is a segment in the surface of a unit sphere that is part of a great circle trough the origin. Sphere segments are represented by two sphere points \f$ p\f$ and \f$ q\f$ plus an oriented plane \f$ h\f$ that contains \f$ p\f$ and \f$ q\f$. The plane determines the sphere segment as follows. Let \f$ c\f$ be the circle in the intersection of \f$ h\f$ and \f$ S_2\f$. Then \f$ s\f$ is that part of \f$ c\f$ that is swept, when we rotate \f$ p\f$ into \f$ q\f$ in counterclockwise rotation around the normal vector of \f$ h\f$ as seen from the positive halfspace. */ class Sphere_segment { public: /// \name Creation /// @{ /*! creates some sphere segment. */ Sphere_segment(); /*! creates a spherical segment spanning the shorter arc from `p1` to `p2` if `shorter_arc == true`. Otherwise the longer arc is created. \pre `p1 != p2` and `p1 != p2.opposite()`. */ Sphere_segment( const Sphere_point& p1, const Sphere_point& p2, bool shorter_arc=true); /*! creates a spherical segment spanning the arc from `p1` to `p2` as part of the oriented circle `c` (`p1 == p2` or `p1 == p2.opposite()` are possible.) \pre `p1` and `p2` are contained in `c`. */ Sphere_segment(const Sphere_point& p1, const Sphere_point& p2, const Sphere_circle& c); /*! creates the spherical segment as part of `c1` that is part of the halfsphere left of the oriented circle `c2`. \pre `c1 != c2` as unoriented circles. */ Sphere_segment(const Sphere_circle& c1, const Sphere_circle& c2); /// @} /// \name Operations /// @{ /*! the source point of `s`. */ const Sphere_point& source() ; /*! the target point of `s`. */ const Sphere_point& target() ; /*! the great circle supporting `s`. */ const Sphere_circle& sphere_circle() ; /*! returns the sperical segment oriented from `target()` to `source()` with the same point set as `s`. */ Sphere_segment opposite() ; /*! returns the sperical segment oriented from `target()` to `source()` with the point set completing `s` to a full circle. */ Sphere_segment complement() ; /*! a segment is short iff it is shorter than a half-circle. */ bool is_short() ; /*! a segment is long iff it is longer than a half-circle. */ bool is_long() ; /*! return true iff `s` is degenerate, i.e.\ source and target are the same. */ bool is_degenerate() ; /*! return true iff `s` is a perfect half-circle, i.e.\ `source().antipode == target()`. */ bool is_halfcircle() ; /*! return true iff `s` contains `p`. */ bool has_on(const Sphere_point& p) ; /*! return true iff `s` contains `p` in its relative interior. */ bool has_in_relative_interior(const Sphere_point& p) ; /// @} }; /* end Sphere_segment */ /*! \ingroup PkgNefS2Ref The type `SFace_cycle_iterator` iterates over a list of `Object_handles`. Each item of that list can either be assigned to `SVertex_handle`, `SHalfedge_handle` or `SHalfloop_handle`. To find out which of these assignment works out, the member functions `is_svertex()`, `is_shalfedge()` and `is_shalfloop()` are provided. \sa `CGAL::Nef_polyhedron_S2::SVertex` \sa `CGAL::Nef_polyhedron_S2::SHalfedge` \sa `CGAL::Nef_polyhedron_S2::SHalfloop` */ class SFace_cycle_iterator { public: /// \name Types /// @{ /*! const handle to SVertex. */ typedef unspecified_type SVertex_handle; /*! const handle to SHalfedge. */ typedef unspecified_type SHalfedge_handle; /*! const handle to SHalfloop. */ typedef unspecified_type SHalfloop_handle; /// @} /// \name Creation /// @{ /*! default constructor. */ SFace_cycle_iterator(); /// @} /// \name Operations /// @{ /*! returns true if the iterator represents a `SVertex_handle`. */ bool is_svertex() const; /*! returns true if the iterator represents a `SHalfedge_handle`. */ bool is_shalfedge() const; /*! returns true if the iterator represents a `SHalfloop_handle`. */ bool is_shalfloop() const; /*! casts the iterator to `SVertex_handle`. */ operator SVertex_handle() const; /*! casts the iterator to `SHalfedge_handle`. */ operator SHalfedge_handle() const; /*! casts the iterator to `SHalfloop_handle`. */ operator SHalfloop_handle() const; /// @} }; /* end SFace_cycle_iterator */ /*! \ingroup PkgNefS2Ref Figures \ref figureNefS2SVertexIncidences and \ref figureNefS2SHalfloopIncidences illustrate the incidences of an sface. An sface is described by its boundaries. An entry item to each boundary cycle can be accessed using the iterator range (`sface_cycles_begin()`/`sface_cycles_end()`). Additionally, `Nef_polyhedron_S2` provides the macro `CGAL_forall_sface_cylces_of`. The iterators are of type `SFace_cycle_const_iterator` and represent either a shalfedge, a shalfloop, or a svertex. \cgalHeading{Creation} There is no need for a user to create a `SFace` explicitly. The class `Nef_polyhedron_S2` manages the needed sfaces internally. \sa `CGAL::Nef_polyhedron_S2` \sa `CGAL::Nef_polyhedron_S2::SVertex` */ class SFace { public: /// \name Types /// The following types are the same as in `Nef_polyhedron_S2`. /// @{ /*! type of mark. */ typedef unspecified_type Mark; /*! list of Object handles. */ typedef unspecified_type Object_list; /*! const handle to Vertex. */ typedef unspecified_type Vertex_const_handle; /*! const handle to Volume. */ typedef unspecified_type Volume_const_handle; /*! const handle to SFace. */ typedef unspecified_type SFace_const_handle; /*! const iterator over the entries to all `sface` cycles of a `sface`. */ typedef unspecified_type SFace_cycle_const_iterator; /// @} /// \name Operations /// @{ /*! the mark of the `sface`. */ const Mark& mark() const; /*! iterator over the entries to all sface cycles of the `sface` . */ SFace_cycle_const_iterator sface_cycle_begin() const; /*! past-the-end iterator. */ SFace_cycle_const_iterator sface_cycle_end() const; /// @} }; /* end SFace */ /*! \ingroup PkgNefS2Ref A shalfedge is a great arc on a sphere map. The figure below depicts the relationship between a shalfedge and its incident shalfedges, svertices, and sfaces on a sphere map. A shalfedge is an oriented sedge between two svertices. It is always paired with a shalfedge pointing in the opposite direction. The `twin()` member function returns this shalfedge of opposite orientation. \anchor figureNefS2SVertexIncidences \image html shalfedge.png "Incidences of an SHalfedge" \image latex shalfedge.png "Incidences of an SHalfedge" The `snext()` member function points to the successor shalfedge around this sface while the `sprev()` member function points to the preceding shalfedge. An successive assignments of the form `se = se->snext()` cycles counterclockwise around the sface (or hole). Similarly, the successive assignments of the form `se = se->snext()->twin()` cycle clockwise around the svertex and traverse all halfedges incident to this svertex. The assignment `se = se->cyclic_adj_succ()` can be used as a shortcut. A const circulator is provided for each of the two circular orders. The circulators are bidirectional and assignable to `SHalfedge_const_handle`. \cgalHeading{Creation} There is no need for a user to create a `SHalfedge` explicitly. The class `Nef_polyhedron_S2` manages the needed shalfedges internally. \sa `CGAL::Nef_polyhedron_S2::SVertex` \sa `CGAL::Nef_polyhedron_S2::SFace` \sa `CGAL::Nef_polyhedron_S2::Sphere_circle` */ class SHalfedge { public: /// \name Types /// The following types are the same as in `Nef_polyhedron_S2`. /// @{ /*! type of mark. */ typedef unspecified_type Mark; /*! sphere circle type stored in SHalfedge. */ typedef unspecified_type Sphere_circle; /*! const handle to SVertex. */ typedef unspecified_type SVertex_const_handle; /*! const handle to SHalfedge. */ typedef unspecified_type SHalfedge_const_handle; /*! const handle to SFace. */ typedef unspecified_type SFace_const_handle; /// @} /// \name Operations /// @{ /*! the mark of the `sedge`. */ const Mark& mark() const; /*! the sphere circle of the `sedge`. */ const Sphere_circle& circle() const; /*! the twin of the `sedge`. */ SHalfedge_const_handle twin() const; /*! the source svertex of the `sedge`. */ SVertex_const_handle source() const; /*! equals `twin()->source()`. */ SVertex_const_handle target() const; /*! the SHalfedge previous to the `sedge` in a sface cycle. */ SHalfedge_const_handle sprev() const; /*! the next SHalfedge of the `sedge` in a sface cycle. */ SHalfedge_const_handle snext() const; /*! the edge before the `sedge` in the cyclic ordered adjacency list of `source()`. */ SHalfedge_const_handle cyclic_adj_pred() const; /*! the edge after the `sedge` in the cyclic ordered adjacency list of `source()`. */ SHalfedge_const_handle cyclic_adj_succ() const; /*! the incident `sface` of the `sedge`. */ SFace_const_handle incident_sface() const; /*! determines whether the `sedge` is in an outer sface cycle. */ bool in_outer_sface_cycle() const; /*! determines whether the `sedge` is in an inner sface cycle. */ bool in_inner_sface_cycle() const; /// @} }; /* end SHalfedge */ /*! \ingroup PkgNefS2Ref A sloop is a great circle on a sphere. A shalfloop is an oriented sloop. It is always paired with a shalfloop whose supporting `Sphere_circle` is pointing in the opposite direction. The `twin()` member function returns this shalfloop of opposite orientation. Each `Nef_polyhedron_S2` can only have one sloop (resp. two shalfloops). The figure below depicts the relationship between a shalfloop and sfaces on a sphere map. \anchor figureNefS2SHalfloopIncidences \image html shalfloopB.png "Incidences of an SHalfloop " \image latex shalfloopB.png "Incidences of an SHalfloop " \cgalHeading{Creation} There is no need for a user to create a `SHalfloop` explicitly. The class `Nef_polyhedron_S2` manages the needed shalfloops internally. \sa `CGAL::Nef_polyhedron_S2::SFace` \sa `CGAL::Nef_polyhedron_S2::Sphere_circle` */ class SHalfloop { public: /// \name Types /// The following types are the same as in `Nef_polyhedron_S2`. /// @{ /*! type of mark. */ typedef unspecified_type Mark; /*! sphere circle type stored in SHalfloop. */ typedef unspecified_type Sphere_circle; /*! const handle to SHalfloop. */ typedef unspecified_type SHalfloop_const_handle; /*! const handle to SFace. */ typedef unspecified_type SFace_const_handle; /// @} /// \name Operations /// @{ /*! the mark of the halfloop. */ const Mark& mark() const; /*! the sphere circle of the halfloop. */ const Sphere_circle& circle() const; /*! the twin of the halfloop. */ SHalfloop_const_handle twin() const; /*! the incident sface of the halfloop. */ SFace_const_handle incident_sface() const; /// @} }; /* end SHalfloop */ /*! \ingroup PkgNefS2Ref Figure \ref figureNefS2SVertexIncidences illustrates the incidence of a svertex on a sphere map. The member function `out_sedge()` returns the first outgoing shalfedge, and `incident_sface()` returns the incident sface. \cgalHeading{Creation} There is no need for a user to create a `SVertex` explicitly. The class `Nef_polyhedron_S2` manages the needed svertices internally. \sa `CGAL::Nef_polyhedron_S2::SHalfedge` \sa `CGAL::Nef_polyhedron_S2::SFace` \sa `CGAL::Nef_polyhedron_S2::Sphere_point` */ class SVertex { public: /// \name Types /// The following types are the same as in `Nef_polyhedron_S2`. /// @{ /*! type of mark. */ typedef unspecified_type Mark; /*! sphere point type stored in SVertex. */ typedef unspecified_type Sphere_point; /*! const handle to SVertex. */ typedef unspecified_type SVertex_const_handle; /*! const handle to SHalfedge. */ typedef unspecified_type SHalfedge_const_handle; /*! const handle to SFace. */ typedef unspecified_type SFace_const_handle; /// @} /// \name Operations /// @{ /*! the mark of the `svertex`. */ const Mark& mark() const; /*! the sphere point of the `svertex`. */ const Sphere_point& point() const; /*! returns |true| if the `svertex` has no adjacent sedges. */ bool is_isolated() const; /*! the twin of the `svertex`. */ SVertex_const_handle twin() const; /*! the first out sedge of the `svertex`. */ SHalfedge_const_handle out_sedge() const; /*! the incident sface of the `svertex`. */ SFace_const_handle incident_sface() const; /// @} }; /* end SVertex */ /*! non-mutable handle to svertex. */ typedef unspecified_type SVertex_const_handle; /*! non-mutable handle to shalfedge. */ typedef unspecified_type SHalfedge_const_handle; /*! non-mutable handle to shalfloop. */ typedef unspecified_type SHalfloop_const_handle; /*! non-mutable handle to sface. */ typedef unspecified_type SFace_const_handle; /*! non-mutable iterator over all svertices. */ typedef unspecified_type SVertex_const_iterator; /*! non-mutable iterator over all shalfedges. */ typedef unspecified_type SHalfedge_const_iterator; /*! non-mutable iterator over all shalfloops. */ typedef unspecified_type SHalfloop_const_iterator; /*! non-mutable iterator over all sfaces. */ typedef unspecified_type SFace_const_iterator; /*! circulating the adjacency list of an svertex `v`. */ typedef unspecified_type SHalfedge_around_svertex_const_circulator; /*! circulating the sface cycle of an sface `f`. */ typedef unspecified_type SHalfedge_around_sface_const_circulator; /*! iterating all sface cycles of an sface `f`. The iterator has method `bool is_svertex()`, `bool is_shalfedge()`, `bool is_shalfloop()`, and can be converted to the corresponding handles `SVertex_const_handle`, `SHalfedge_const_handle`, or `SHalfloop_const_handle`. */ typedef unspecified_type SFace_cycle_const_iterator; /*! attributes of objects (vertices, edges, faces). */ typedef unspecified_type Mark; /*! size type */ typedef unspecified_type size_type; /*! construction selection. */ enum Boundary { EXCLUDED, INCLUDED }; /*! construction selection. */ enum Content { EMPTY, COMPLETE }; /// @} /// \name Creation /// @{ /*! creates an instance `N` of type `Nef_polyhedron_S2` and initializes it to the empty set if `sphere == EMPTY` and to the whole sphere if `sphere == COMPLETE`. */ Nef_polyhedron_S2(Content sphere = EMPTY); /*! creates a Nef polyhedron `N` containing the half-sphere left of `c` including `c` if `circle==INCLUDED`, excluding `c` if `circle==EXCLUDED`. */ Nef_polyhedron_S2(Sphere_circle c, Boundary circle = INCLUDED); /*! creates a Nef polyhedron `N` from the set of sphere segments in the iterator range `[first,beyond)`. If the set of sphere segments is a simple polygon that separates the sphere surface into two regions, then the polygonal region that is left of the segment `*first` is selected. The polygonal region includes its boundary if `b = INCLUDED` and excludes the boundary otherwise. `Forward_iterator` has to be an iterator with value type `Sphere_segment`. */ template Nef_polyhedron_S2(Forward_iterator first, Forward_iterator beyond, Boundary b = INCLUDED); /// @} /// \name Operations /// @{ /*! makes `N` the empty set if `plane == EMPTY` and the full plane if `plane == COMPLETE`. */ void clear(Content plane = EMPTY) ; /*! returns true if `N` is empty, false otherwise. */ bool is_empty() ; /*! returns true if `N` is the whole sphere, false otherwise. */ bool is_sphere() ; /// @} /// \name Constructive Operations /// Additionally there are operators `*,+,-,^,!` which implement the /// binary operations intersection, union, /// difference, symmetric difference, and the unary /// operation complement respectively. There are also the /// corresponding modification operations `<,<=,>,>=,==,!=`. /// /// There are also comparison operations like `<,<=,>,>=,==,!=` which /// implement the relations subset, subset or equal, superset, /// superset or equal, equality, inequality, respectively. /// @{ /*! returns the complement of `N` in the plane. */ Nef_polyhedron_S2 complement() ; /*! returns the interior of `N`. */ Nef_polyhedron_S2 interior() ; /*! returns the closure of `N`. */ Nef_polyhedron_S2 closure() ; /*! returns the boundary of `N`. */ Nef_polyhedron_S2 boundary() ; /*! returns the regularized polyhedron (closure of interior). */ Nef_polyhedron_S2 regularization() ; /*! returns `N` \f$ \cap\f$ `N1`. */ Nef_polyhedron_S2 intersection(const Nef_polyhedron_S2& N1) ; /*! returns `N` \f$ \cup\f$ `N1`. */ Nef_polyhedron_S2 join(const Nef_polyhedron_S2& N1) ; /*! returns `N` \f$ -\f$ `N1`. */ Nef_polyhedron_S2 difference(const Nef_polyhedron_S2& N1) ; /*! returns the symmectric difference `N - T` \f$ \cup\f$ `T - N`. */ Nef_polyhedron_S2 symmetric_difference( const Nef_polyhedron_S2& N1) ; /// @} /// \name Statistics and Integrity /// @{ /*! returns the number of svertices. */ Size_type number_of_svertices() ; /*! returns the number of shalfedges. */ Size_type number_of_shalfedges() ; /*! returns the number of sedges. */ Size_type number_of_sedges() ; /*! returns the number of shalfloops. */ Size_type number_of_shalfloops() ; /*! returns the number of sloops. */ Size_type number_of_sloops() ; /*! returns the number of sfaces. */ Size_type number_of_sfaces() ; /*! returns the number of sface cycles. */ Size_type number_of_sface_cycles() ; /*! calculates the number of connected components of `P`. */ Size_type number_of_connected_components() ; /*! print the statistics of `P`: the number of vertices, edges, and faces. */ void print_statistics(std::ostream& os = std::cout) ; /*! checks the link structure and the genus of `P`. */ void check_integrity_and_topological_planarity(bool faces=true) ; /// @} /// \name Types /// @{ /*! a generic handle to an object of the underlying plane map. The kind of object `(vertex, halfedge, face)` can be determined and the object can be assigned to a corresponding handle by the three functions: - `bool assign(Vertex_const_handle& h, Object_handle)` - `bool assign(Halfedge_const_handle& h, Object_handle)` - `bool assign(Face_const_handle& h, Object_handle)` where each function returns `true` iff the assignment to `h` was done. */ typedef unspecified_type Object_handle; /// @} /// \name Operations /// @{ /*! returns true iff the object `h` is contained in the set represented by `N`. */ bool contains(Object_handle h) ; /*! returns true iff the object `h` is contained in the \f$ 1\f$-skeleton of `N`. */ bool contained_in_boundary(Object_handle h) ; /*! returns a generic handle `h` to an object (face, halfedge, vertex) of the underlying plane map that contains the point `p` in its relative interior. The point `p` is contained in the set represented by `N` if `N.contains(h)` is true. The location mode flag `m` allows one to choose between different point location strategies. */ Object_handle locate(const Sphere_point& p) ; /*! returns a handle `h` with `N.contains(h)` that can be converted to a `Vertex_/Halfedge_/Face_const_handle` as described above. The object returned is intersected by the ray starting in `p` with direction `d` and has minimal distance to `p`. The operation returns an empty `Object_handle` if the ray shoot along `d` does not hit any object `h` of `N` with `N.contains(h)`. */ Object_handle ray_shoot(const Sphere_point& p, const Sphere_direction& d) ; /*! returns a handle `h` that can be converted to a `Vertex_/Halfedge_const_handle` as described above. The object returned is part of the \f$ 1\f$-skeleton of `N`, intersected by the ray starting in `p` with direction `d` and has minimal distance to `p`. The operation returns an empty `Object_handle` if the ray shoot along `d` does not hit any \f$ 1\f$-skeleton object `h` of `N`. The location mode flag `m` allows one to choose between different point location strategies. */ Object_handle ray_shoot_to_boundary(const Sphere_point& p, const Sphere_direction& d) ; /// @} /// \name Iteration /// The list of all objects can be accessed via iterator ranges. For /// comfortable iteration we also provide iterations macros. The /// iterator range access operations are of the following kind: /// - `SVertex_iterator svertices_begin()/svertices_end()` /// - `SHalfedge_iterator shalfedges_begin()/shalfedges_end()` /// - `SHalfloop_iterator shalfloops_begin()/shalfloops_end()` /// - `SFace_iterator sfaces_begin()/sfaces_end()` /// /// The macros are then /// - `CGAL_forall_svertices(v,M)`, /// - `CGAL_forall_shalfedges(e,M)`, /// - `CGAL_forall_sfaces(f,M)`, /// - `CGAL_forall_sface_cycles_of(fc,F)` /// /// where `M` is a sphere map and `F` is a sface. /// @{ /*! returns true iff there is a shalfloop. */ bool has_shalfloop() const; /*! returns access to the sloop. */ SHalfloop_const_handle shalfloop() const; /// @} }; /* end Nef_polyhedron_S2 */ /*! returns true iff `c1` and `c2` are equal as unoriented circles. \relates Nef_polyhedron_S2::Sphere_circle */ bool equal_as_sets(const Nef_polyhedron_S2::Sphere_circle c1, const Nef_polyhedron_S2::Sphere_circle c2); } /* end namespace CGAL */