2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 * @author Jocelyn Meyron (\c jocelyn.meyron@liris.cnrs.fr )
20 * Laboratoire d'InfoRmatique en Image et Systemes d'information - LIRIS (CNRS, UMR 5205), CNRS, France
24 * Implementation of inline methods defined in PlaneProbingNeighborhood.h
26 * This file is part of the DGtal library.
30//////////////////////////////////////////////////////////////////////////////
32#include "DGtal/geometry/helpers/PlaneProbingEstimatorHelper.h"
33//////////////////////////////////////////////////////////////////////////////
35///////////////////////////////////////////////////////////////////////////////
36// INITIALIZATION of static data.
37///////////////////////////////////////////////////////////////////////////////
39template < typename TPredicate >
40const typename DGtal::PlaneProbingNeighborhood<TPredicate>::PointOnProbingRay DGtal::PlaneProbingNeighborhood<TPredicate>::myNeighborhood[6] =
42 PointOnProbingRay({0, 1, 2}), PointOnProbingRay({0, 2, 1}),
43 PointOnProbingRay({1, 2, 0}), PointOnProbingRay({1, 0, 2}),
44 PointOnProbingRay({2, 0, 1}), PointOnProbingRay({2, 1, 0}),
47///////////////////////////////////////////////////////////////////////////////
48// IMPLEMENTATION of inline methods.
49///////////////////////////////////////////////////////////////////////////////
51///////////////////////////////////////////////////////////////////////////////
52// ----------------------- Standard services ------------------------------
54// ------------------------------------------------------------------------
55template < typename TPredicate >
57DGtal::PlaneProbingNeighborhood<TPredicate>::
58PlaneProbingNeighborhood(Predicate const& aPredicate, Point const& aQ, Triangle const& aM)
59 : myPredicate(aPredicate), myQ(aQ), myM(aM)
62// ------------------------------------------------------------------------
63template < typename TPredicate >
65DGtal::PlaneProbingNeighborhood<TPredicate>::~PlaneProbingNeighborhood()
68///////////////////////////////////////////////////////////////////////////////
69// ----------------------- Plane Probing services ------------------------------
71// ------------------------------------------------------------------------
72template < typename TPredicate >
73template < typename TPointAdapter >
76DGtal::PlaneProbingNeighborhood<TPredicate>::closestPointInList (std::vector<TPointAdapter> const& aPoints) const
78 auto b = aPoints.begin();
79 auto e = aPoints.end();
83 for (auto it = ++b; it != e; ++it) {
84 if (isSmallest(relativePoint(minPoint), relativePoint(*it))) {
91// ------------------------------------------------------------------------
92template < typename TPredicate >
94typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
95DGtal::PlaneProbingNeighborhood<TPredicate>::classify (std::array<bool, 6> const& aState) const
98 for (int i = 0; i < 6; ++i)
108 // All the points are not in the plane => algorithm stops
109 return HexagonState::Empty;
111 else if (inside == 1)
113 // Only one point in the plane => algorithm continues
114 return HexagonState::Planar;
116 else if (inside == 2 || inside == 3)
118 // two points aligned with q in the plane => algorithm stops
119 for (int i = 0; i < 3; ++i)
121 if (aState[i] && aState[(i + 3) % 6])
123 return HexagonState::NonConvex;
127 // three consecutive points where the two extremities are in the plane but not the middle one => algorithm stops
128 // otherwise => algorithm continues
129 for (int i = 0; i < 6; ++i)
131 if (aState[i] && !aState[(i + 1) % 6] && aState[(i + 2) % 6])
133 return HexagonState::NonPlanar;
137 return HexagonState::Planar;
140 // Strictly more than 3 points in the plane => algorithm stops
141 return HexagonState::NonConvex;
144// ------------------------------------------------------------------------
145template < typename TPredicate >
148DGtal::PlaneProbingNeighborhood<TPredicate>::
149setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
151 myNeighbors = aNeighbors;
154// ------------------------------------------------------------------------
155template < typename TPredicate >
157typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
158DGtal::PlaneProbingNeighborhood<TPredicate>::
161 // One should call hexagonState before closestCandidate, and check the return value
162 // to ensure that there is at least one point in the plane in the H-neighbhorhood
163 ASSERT(! myCandidates.empty());
165 PointOnProbingRay closest = closestPointInList(myCandidates);
167 return getOperation(closest);
170// ------------------------------------------------------------------------
171template < typename TPredicate >
173typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
174DGtal::PlaneProbingNeighborhood<TPredicate>::
175getOperation (PointOnProbingRay const& aClosest) const
179 { 1, -1, -aClosest.position() },
183// ------------------------------------------------------------------------
184template < typename TPredicate >
187DGtal::PlaneProbingNeighborhood<TPredicate>::isNeighbor (PointOnProbingRay const& r) const
189 if (myNeighbors.empty())
194 return std::find(myNeighbors.begin(), myNeighbors.end(), r) != myNeighbors.end();
197// ------------------------------------------------------------------------
198template < typename TPredicate >
201DGtal::PlaneProbingNeighborhood<TPredicate>::
202isSmallest (Point const& aX, Point const& aY) const
204 Integer zero = DGtal::NumberTraits<Integer>::ZERO;
206 std::array<Point, 5> ps;
207 for (int i = 0; i < 3; ++i)
214 Integer res = DGtal::detail::distToSphere(ps);
217 } else if (res < zero) {
224// ------------------------------------------------------------------------
225template < typename TPredicate >
226template < typename TPointAdapter >
228typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229DGtal::PlaneProbingNeighborhood<TPredicate>::
230relativePoint (TPointAdapter const& aPoint) const
232 return aPoint.relativePoint(myM);
235// ------------------------------------------------------------------------
236template < typename TPredicate >
237template < typename TPointAdapter >
239typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
240DGtal::PlaneProbingNeighborhood<TPredicate>::
241absolutePoint (TPointAdapter const& aPoint) const
243 return myQ + relativePoint(aPoint);
247///////////////////////////////////////////////////////////////////////////////
248// Interface - public :
251 * Writes/Displays the object on an output stream.
252 * @param out the output stream where the object is written.
254template <typename TPredicate>
257DGtal::PlaneProbingNeighborhood<TPredicate>::selfDisplay ( std::ostream & out ) const
259 out << "[PlaneProbingNeighborhood]";
263 * Checks the validity/consistency of the object.
264 * @return 'true' if the object is valid, 'false' otherwise.
266template <typename TPredicate>
267inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
274///////////////////////////////////////////////////////////////////////////////
275// Implementation of inline functions //
277template <typename TPredicate>
280DGtal::operator<< ( std::ostream & out,
281 const PlaneProbingNeighborhood<TPredicate> & object )
283 object.selfDisplay( out );
288///////////////////////////////////////////////////////////////////////////////