diff --git a/AABB_tree/examples/AABB_tree/AABB_segment_2_example.cpp b/AABB_tree/examples/AABB_tree/AABB_segment_2_example.cpp index 62cbadafff8..b759aa91a8c 100644 --- a/AABB_tree/examples/AABB_tree/AABB_segment_2_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_segment_2_example.cpp @@ -4,7 +4,9 @@ #include #include #include +#include #include +#include typedef CGAL::Simple_cartesian K; @@ -13,42 +15,73 @@ typedef K::FT FT; typedef K::Segment_2 Segment; typedef K::Point_2 Point; -typedef std::list::iterator Iterator; -typedef CGAL::AABB_segment_primitive_2 Primitive; -typedef CGAL::AABB_traits_2 Traits; -typedef CGAL::AABB_tree Tree; +typedef std::list SegmentRange; +typedef SegmentRange::iterator Iterator_seg; +typedef CGAL::AABB_segment_primitive_2 Primitive_seg; +typedef CGAL::AABB_traits_2 Traits_seg; +typedef CGAL::AABB_tree Tree_seg; + +typedef std::vector PointRange; +typedef PointRange::iterator Iterator_pr; +typedef CGAL::AABB_polyline_segment_primitive_2 Primitive_pr; +typedef CGAL::AABB_traits_2 Traits_pr; +typedef CGAL::AABB_tree Tree_pr; + +typedef CGAL::Polygon_2 Polygon; +typedef Polygon::iterator Iterator_poly; +typedef CGAL::AABB_polyline_segment_primitive_2 Primitive_poly; +typedef CGAL::AABB_traits_2 Traits_poly; +typedef CGAL::AABB_tree Tree_poly; int main() { - Point a(0.0, 0.0); - Point b(2.0, 1.0); - Point c(3.0, 4.0); - Point d(1.0, 6.0); - Point e(-1.0, 3.0); + Point a(0.0, 0.0); + Point b(2.0, 1.0); + Point c(3.0, 4.0); + Point d(1.0, 6.0); + Point e(-1.0, 3.0); - std::list segments; - segments.push_back(Segment(a, b)); - segments.push_back(Segment(b, c)); - segments.push_back(Segment(c, d)); - segments.push_back(Segment(d, e)); - segments.push_back(Segment(e, a)); + std::list seg; + seg.push_back(Segment(a, b)); + seg.push_back(Segment(b, c)); + seg.push_back(Segment(c, d)); + seg.push_back(Segment(d, e)); + seg.push_back(Segment(e, a)); - // // constructs the AABB tree and the internal search tree for - // // efficient distance computations. - Tree tree(segments.begin(), segments.end()); - // tree.accelerate_distance_queries(); + std::vector polyline = { a, b, c, d, e }; - // // counts #intersections with a segment query - Segment segment_query(Point(1.0, 0.0), Point(0.0, 7.0)); - std::cout << tree.number_of_intersected_primitives(segment_query) - << " intersections(s) with segment" << std::endl; + Polygon poly(polyline.begin(), polyline.end()); + // // constructs the AABB tree and the internal search tree for + // // efficient distance computations. + Tree_seg tree_seg(seg.begin(), seg.end()); + Tree_pr tree_pr(polyline.begin(), polyline.end(), polyline); + Tree_poly tree_poly(poly.begin(), poly.end(), poly); - // computes the closest point from a point query - Point point_query(1.5, 3.0); - Point closest = tree.closest_point(point_query); + tree_seg.accelerate_distance_queries(); + tree_pr.accelerate_distance_queries(); + tree_poly.accelerate_distance_queries(); - //std::cerr << "closest point is: " << closest << std::endl; - return EXIT_SUCCESS; + // // counts #intersections with a segment query + + Segment segment_query(Point(1.0, 0.0), Point(0.0, 7.0)); + std::cout << tree_seg.number_of_intersected_primitives(segment_query) + << " intersections(s) with segment" << std::endl; + + std::cout << tree_pr.number_of_intersected_primitives(segment_query) + << " intersections(s) with segment" << std::endl; + + std::cout << tree_poly.number_of_intersected_primitives(segment_query) + << " intersections(s) with segment" << std::endl; + + // computes the closest point from a point query + Point point_query(1.5, 3.0); + Point closest = tree_seg.closest_point(point_query); + std::cerr << "closest point is: " << closest << std::endl; + closest = tree_pr.closest_point(point_query); + std::cerr << "closest point is: " << closest << std::endl; + closest = tree_poly.closest_point(point_query); + std::cerr << "closest point is: " << closest << std::endl; + return EXIT_SUCCESS; } diff --git a/AABB_tree/include/CGAL/AABB_polyline_segment_primitive_2.h b/AABB_tree/include/CGAL/AABB_polyline_segment_primitive_2.h new file mode 100644 index 00000000000..c2bbbf6da95 --- /dev/null +++ b/AABB_tree/include/CGAL/AABB_polyline_segment_primitive_2.h @@ -0,0 +1,110 @@ +// Copyright (c) 2024 GeometryFactory. +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org). +// +// $URL$ +// $Id$ +// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial +// +// +// Author(s) : Sebastien Loriot +// + + +#ifndef CGAL_AABB_POLYLINE_SEGMENT_PRIMITIVE_2_H_ +#define CGAL_AABB_POLYLINE_SEGMENT_PRIMITIVE_2_H_ + +#include + +#include + +#include +#include + +namespace CGAL { + +namespace internal { + template + struct Segment_2_from_point_iterator_property_map { + //classical typedefs + typedef Iterator key_type; + typedef typename GeomTraits::Segment_2 value_type; + typedef typename GeomTraits::Segment_2 reference; // The segments are created on the fly, so working with references is not possible. + typedef boost::readable_property_map_tag category; + typedef Segment_2_from_point_iterator_property_map Self; + + Segment_2_from_point_iterator_property_map(Iterator b, Iterator e) : begin(b), end(e) {} + Segment_2_from_point_iterator_property_map() {} + + inline friend reference // Cannot return reference as the Segment does not exist, only the points exist. + get(Self s, key_type it) + { + typename Iterator::value_type& p = *it; + it++; + if (it == s.end) + return typename GeomTraits::Construct_segment_2()(p, *s.begin); + else + return typename GeomTraits::Construct_segment_2()( p, *it ); + } + + Iterator begin, end; + }; +}//namespace internal + + +/*! + * \ingroup PkgAABBTreeRef + * Primitive type that uses as identifier an iterator with a 3D segment as `value_type`. + * The iterator from which the primitive is built should not be invalided + * while the AABB tree holding the primitive is in use. + * + * \cgalModels{AABBPrimitive} + * + * \tparam GeomTraits is a traits class providing the nested type `Point_2` and `Segment_2`. + * It also provides the functor `Construct_source_2` that has an operator taking a `Segment_2` + * and returning its source as a type convertible to `Point_2`. + * \tparam Iterator is a model of `ForwardIterator` with its value type convertible to `GeomTraits::Segment_2` + * \tparam CacheDatum is either `CGAL::Tag_true` or `CGAL::Tag_false`. In the former case, + * the datum is stored in the primitive, while in the latter it is + * constructed on the fly to reduce the memory footprint. + * The default is `CGAL::Tag_false` (datum is not stored). + * + * \sa `AABBPrimitive` + * \sa `AABB_primitive` + * \sa `AABB_triangle_primitive_3` + * \sa `AABB_halfedge_graph_segment_primitive` + * \sa `AABB_face_graph_triangle_primitive` + */ +template < class PointRange, + class GeomTraits, + class Iterator, + class CacheDatum=Tag_false> +class AABB_polyline_segment_primitive_2 +#ifndef DOXYGEN_RUNNING + : public AABB_primitive< Iterator, + internal::Segment_2_from_point_iterator_property_map, + Input_iterator_property_map, + Tag_true, + CacheDatum > +#endif +{ + typedef AABB_primitive< Iterator, + internal::Segment_2_from_point_iterator_property_map, + Input_iterator_property_map, + Tag_true, + CacheDatum > Base; +public: + AABB_polyline_segment_primitive_2(Iterator it, PointRange& poly) : Base(it) {} + + /// \internal + static typename Base::Shared_data construct_shared_data(PointRange& range) { + return std::make_pair(internal::Segment_2_from_point_iterator_property_map(range.begin(), range.end()), Input_iterator_property_map()); + } +}; + +} // end namespace CGAL + +#include + +#endif // CGAL_AABB_POLYLINE_SEGMENT_PRIMITIVE_2_H_