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 >
74typename DGtal::PlaneProbingNeighborhood<TPredicate>::PointOnProbingRay
75DGtal::PlaneProbingNeighborhood<TPredicate>::closestPointInList (std::vector<PointOnProbingRay> const& aPoints) const
77 const auto N = aPoints.size();
82 PointOnProbingRay minPoint = aPoints[N-1];
83 for (Dimension k = 0; k < (Dimension)((int)N-1); ++k) {
84 if (isSmallest(relativePoint(minPoint), relativePoint(aPoints[k]))) {
85 minPoint = aPoints[k];
92// ------------------------------------------------------------------------
93template < typename TPredicate >
95typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
96DGtal::PlaneProbingNeighborhood<TPredicate>::classify (std::array<bool, 6> const& aState) const
99 for (int i = 0; i < 6; ++i)
109 // All the points are not in the plane => algorithm stops
110 return HexagonState::Empty;
112 else if (inside == 1)
114 // Only one point in the plane => algorithm continues
115 return HexagonState::Planar;
117 else if (inside == 2 || inside == 3)
119 // two points aligned with q in the plane => algorithm stops
120 for (int i = 0; i < 3; ++i)
122 if (aState[i] && aState[(i + 3) % 6])
124 return HexagonState::NonConvex;
128 // three consecutive points where the two extremities are in the plane but not the middle one => algorithm stops
129 // otherwise => algorithm continues
130 for (int i = 0; i < 6; ++i)
132 if (aState[i] && !aState[(i + 1) % 6] && aState[(i + 2) % 6])
134 return HexagonState::NonPlanar;
138 return HexagonState::Planar;
141 // Strictly more than 3 points in the plane => algorithm stops
142 return HexagonState::NonConvex;
145// ------------------------------------------------------------------------
146template < typename TPredicate >
149DGtal::PlaneProbingNeighborhood<TPredicate>::
150setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
152 myNeighbors = aNeighbors;
155// ------------------------------------------------------------------------
156template < typename TPredicate >
158typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
159DGtal::PlaneProbingNeighborhood<TPredicate>::
162 // One should call hexagonState before closestCandidate, and check the return value
163 // to ensure that there is at least one point in the plane in the H-neighbhorhood
164 ASSERT(! myCandidates.empty());
166 PointOnProbingRay closest = closestPointInList(myCandidates);
168 return getOperation(closest);
171// ------------------------------------------------------------------------
172template < typename TPredicate >
174typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
175DGtal::PlaneProbingNeighborhood<TPredicate>::
176getOperation (PointOnProbingRay const& aClosest) const
180 { 1, -1, -aClosest.index() },
184// ------------------------------------------------------------------------
185template < typename TPredicate >
188DGtal::PlaneProbingNeighborhood<TPredicate>::isNeighbor (PointOnProbingRay const& r) const
190 if (myNeighbors.empty())
195 return std::find(myNeighbors.begin(), myNeighbors.end(), r) != myNeighbors.end();
198// ------------------------------------------------------------------------
199template < typename TPredicate >
202DGtal::PlaneProbingNeighborhood<TPredicate>::
203isSmallest (Point const& aX, Point const& aY) const
205 Integer zero = DGtal::NumberTraits<Integer>::ZERO;
207 std::array<Point, 5> ps;
208 for (int i = 0; i < 3; ++i)
215 Integer res = DGtal::detail::distToSphere(ps);
218 } else if (res < zero) {
225// ------------------------------------------------------------------------
226template < typename TPredicate >
228typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229DGtal::PlaneProbingNeighborhood<TPredicate>::
230relativePoint (PointOnProbingRay const& aRay) const
232 return -myM[aRay.sigma(0)] + myM[aRay.sigma(1)] + myM[aRay.sigma(2)] * aRay.index();
235// ------------------------------------------------------------------------
236template < typename TPredicate >
238typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
239DGtal::PlaneProbingNeighborhood<TPredicate>::
240absolutePoint (PointOnProbingRay const& aRay) const
242 return myQ + relativePoint(aRay);
246///////////////////////////////////////////////////////////////////////////////
247// Interface - public :
250 * Writes/Displays the object on an output stream.
251 * @param out the output stream where the object is written.
253template <typename TPredicate>
256DGtal::PlaneProbingNeighborhood<TPredicate>::selfDisplay ( std::ostream & out ) const
258 out << "[PlaneProbingNeighborhood]";
262 * Checks the validity/consistency of the object.
263 * @return 'true' if the object is valid, 'false' otherwise.
265template <typename TPredicate>
266inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
273///////////////////////////////////////////////////////////////////////////////
274// Implementation of inline functions //
276template <typename TPredicate>
279DGtal::operator<< ( std::ostream & out,
280 const PlaneProbingNeighborhood<TPredicate> & object )
282 object.selfDisplay( out );
287///////////////////////////////////////////////////////////////////////////////