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 ///////////////////////////////////////////////////////////////////////////////
39 template < typename TPredicate >
40 const 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 // ------------------------------------------------------------------------
55 template < typename TPredicate >
57 DGtal::PlaneProbingNeighborhood<TPredicate>::
58 PlaneProbingNeighborhood(Predicate const& aPredicate, Point const& aQ, Triangle const& aM)
59 : myPredicate(aPredicate), myQ(aQ), myM(aM)
62 // ------------------------------------------------------------------------
63 template < typename TPredicate >
65 DGtal::PlaneProbingNeighborhood<TPredicate>::~PlaneProbingNeighborhood()
68 ///////////////////////////////////////////////////////////////////////////////
69 // ----------------------- Plane Probing services ------------------------------
71 // ------------------------------------------------------------------------
72 template < typename TPredicate >
73 template < typename TPointAdapter >
76 DGtal::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 // ------------------------------------------------------------------------
92 template < typename TPredicate >
94 typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
95 DGtal::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 // ------------------------------------------------------------------------
145 template < typename TPredicate >
148 DGtal::PlaneProbingNeighborhood<TPredicate>::
149 setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
151 myNeighbors = aNeighbors;
154 // ------------------------------------------------------------------------
155 template < typename TPredicate >
157 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
158 DGtal::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 // ------------------------------------------------------------------------
171 template < typename TPredicate >
173 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
174 DGtal::PlaneProbingNeighborhood<TPredicate>::
175 getOperation (PointOnProbingRay const& aClosest) const
179 { 1, -1, -aClosest.position() },
183 // ------------------------------------------------------------------------
184 template < typename TPredicate >
187 DGtal::PlaneProbingNeighborhood<TPredicate>::isNeighbor (PointOnProbingRay const& r) const
189 if (myNeighbors.empty())
194 return std::find(myNeighbors.begin(), myNeighbors.end(), r) != myNeighbors.end();
197 // ------------------------------------------------------------------------
198 template < typename TPredicate >
201 DGtal::PlaneProbingNeighborhood<TPredicate>::
202 isSmallest (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 // ------------------------------------------------------------------------
225 template < typename TPredicate >
226 template < typename TPointAdapter >
228 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229 DGtal::PlaneProbingNeighborhood<TPredicate>::
230 relativePoint (TPointAdapter const& aPoint) const
232 return aPoint.relativePoint(myM);
235 // ------------------------------------------------------------------------
236 template < typename TPredicate >
237 template < typename TPointAdapter >
239 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
240 DGtal::PlaneProbingNeighborhood<TPredicate>::
241 absolutePoint (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.
254 template <typename TPredicate>
257 DGtal::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.
266 template <typename TPredicate>
267 inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
274 ///////////////////////////////////////////////////////////////////////////////
275 // Implementation of inline functions //
277 template <typename TPredicate>
280 DGtal::operator<< ( std::ostream & out,
281 const PlaneProbingNeighborhood<TPredicate> & object )
283 object.selfDisplay( out );
288 ///////////////////////////////////////////////////////////////////////////////