Loading [MathJax]/extensions/TeX/AMSsymbols.js
DGtal 2.0.0
PlaneProbingNeighborhood.ih
1/**
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.
6 *
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.
11 *
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/>.
14 *
15 **/
16
17/**
18 * @file
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
21 *
22 * @date 2020/12/04
23 *
24 * Implementation of inline methods defined in PlaneProbingNeighborhood.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29
30//////////////////////////////////////////////////////////////////////////////
31#include <cstdlib>
32#include "DGtal/geometry/helpers/PlaneProbingEstimatorHelper.h"
33//////////////////////////////////////////////////////////////////////////////
34
35///////////////////////////////////////////////////////////////////////////////
36// INITIALIZATION of static data.
37///////////////////////////////////////////////////////////////////////////////
38
39template < typename TPredicate >
40const typename DGtal::PlaneProbingNeighborhood<TPredicate>::PointOnProbingRay DGtal::PlaneProbingNeighborhood<TPredicate>::myNeighborhood[6] =
41{
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}),
45};
46
47///////////////////////////////////////////////////////////////////////////////
48// IMPLEMENTATION of inline methods.
49///////////////////////////////////////////////////////////////////////////////
50
51///////////////////////////////////////////////////////////////////////////////
52// ----------------------- Standard services ------------------------------
53
54// ------------------------------------------------------------------------
55template < typename TPredicate >
56inline
57DGtal::PlaneProbingNeighborhood<TPredicate>::
58PlaneProbingNeighborhood(Predicate const& aPredicate, Point const& aQ, Triangle const& aM)
59 : myPredicate(aPredicate), myQ(aQ), myM(aM)
60{}
61
62// ------------------------------------------------------------------------
63template < typename TPredicate >
64inline
65DGtal::PlaneProbingNeighborhood<TPredicate>::~PlaneProbingNeighborhood()
66{}
67
68///////////////////////////////////////////////////////////////////////////////
69// ----------------------- Plane Probing services ------------------------------
70
71// ------------------------------------------------------------------------
72template < typename TPredicate >
73template < typename TPointAdapter >
74inline
75TPointAdapter
76DGtal::PlaneProbingNeighborhood<TPredicate>::closestPointInList (std::vector<TPointAdapter> const& aPoints) const
77{
78 auto b = aPoints.begin();
79 auto e = aPoints.end();
80 ASSERT(b != e);
81 auto minPoint = *b;
82
83 for (auto it = ++b; it != e; ++it) {
84 if (isSmallest(relativePoint(minPoint), relativePoint(*it))) {
85 minPoint = *it;
86 }
87 }
88 return minPoint;
89}
90
91// ------------------------------------------------------------------------
92template < typename TPredicate >
93inline
94typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
95DGtal::PlaneProbingNeighborhood<TPredicate>::classify (std::array<bool, 6> const& aState) const
96{
97 int inside = 0;
98 for (int i = 0; i < 6; ++i)
99 {
100 if (aState[i])
101 {
102 inside++;
103 }
104 }
105
106 if (inside == 0)
107 {
108 // All the points are not in the plane => algorithm stops
109 return HexagonState::Empty;
110 }
111 else if (inside == 1)
112 {
113 // Only one point in the plane => algorithm continues
114 return HexagonState::Planar;
115 }
116 else if (inside == 2 || inside == 3)
117 {
118 // two points aligned with q in the plane => algorithm stops
119 for (int i = 0; i < 3; ++i)
120 {
121 if (aState[i] && aState[(i + 3) % 6])
122 {
123 return HexagonState::NonConvex;
124 }
125 }
126
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)
130 {
131 if (aState[i] && !aState[(i + 1) % 6] && aState[(i + 2) % 6])
132 {
133 return HexagonState::NonPlanar;
134 }
135 }
136
137 return HexagonState::Planar;
138 }
139
140 // Strictly more than 3 points in the plane => algorithm stops
141 return HexagonState::NonConvex;
142}
143
144// ------------------------------------------------------------------------
145template < typename TPredicate >
146inline
147void
148DGtal::PlaneProbingNeighborhood<TPredicate>::
149setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
150{
151 myNeighbors = aNeighbors;
152}
153
154// ------------------------------------------------------------------------
155template < typename TPredicate >
156inline
157typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
158DGtal::PlaneProbingNeighborhood<TPredicate>::
159closestCandidate ()
160{
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());
164
165 PointOnProbingRay closest = closestPointInList(myCandidates);
166
167 return getOperation(closest);
168}
169
170// ------------------------------------------------------------------------
171template < typename TPredicate >
172inline
173typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
174DGtal::PlaneProbingNeighborhood<TPredicate>::
175getOperation (PointOnProbingRay const& aClosest) const
176{
177 return {
178 aClosest.sigma(),
179 { 1, -1, -aClosest.position() },
180 };
181}
182
183// ------------------------------------------------------------------------
184template < typename TPredicate >
185inline
186bool
187DGtal::PlaneProbingNeighborhood<TPredicate>::isNeighbor (PointOnProbingRay const& r) const
188{
189 if (myNeighbors.empty())
190 {
191 return true;
192 }
193
194 return std::find(myNeighbors.begin(), myNeighbors.end(), r) != myNeighbors.end();
195}
196
197// ------------------------------------------------------------------------
198template < typename TPredicate >
199inline
200bool
201DGtal::PlaneProbingNeighborhood<TPredicate>::
202isSmallest (Point const& aX, Point const& aY) const
203{
204 Integer zero = DGtal::NumberTraits<Integer>::ZERO;
205
206 std::array<Point, 5> ps;
207 for (int i = 0; i < 3; ++i)
208 {
209 ps[i] = -myM[i];
210 }
211 ps[3] = aX;
212 ps[4] = aY;
213
214 Integer res = DGtal::detail::distToSphere(ps);
215 if (res == zero) {
216 return aY < aX;
217 } else if (res < zero) {
218 return true;
219 } else {
220 return false;
221 }
222}
223
224// ------------------------------------------------------------------------
225template < typename TPredicate >
226template < typename TPointAdapter >
227inline
228typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229DGtal::PlaneProbingNeighborhood<TPredicate>::
230relativePoint (TPointAdapter const& aPoint) const
231{
232 return aPoint.relativePoint(myM);
233}
234
235// ------------------------------------------------------------------------
236template < typename TPredicate >
237template < typename TPointAdapter >
238inline
239typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
240DGtal::PlaneProbingNeighborhood<TPredicate>::
241absolutePoint (TPointAdapter const& aPoint) const
242{
243 return myQ + relativePoint(aPoint);
244}
245
246
247///////////////////////////////////////////////////////////////////////////////
248// Interface - public :
249
250/**
251 * Writes/Displays the object on an output stream.
252 * @param out the output stream where the object is written.
253 */
254template <typename TPredicate>
255inline
256void
257DGtal::PlaneProbingNeighborhood<TPredicate>::selfDisplay ( std::ostream & out ) const
258{
259 out << "[PlaneProbingNeighborhood]";
260}
261
262/**
263 * Checks the validity/consistency of the object.
264 * @return 'true' if the object is valid, 'false' otherwise.
265 */
266template <typename TPredicate>
267inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
268{
269 return true;
270}
271
272
273
274///////////////////////////////////////////////////////////////////////////////
275// Implementation of inline functions //
276
277template <typename TPredicate>
278inline
279std::ostream&
280DGtal::operator<< ( std::ostream & out,
281 const PlaneProbingNeighborhood<TPredicate> & object )
282{
283 object.selfDisplay( out );
284 return out;
285}
286
287// //
288///////////////////////////////////////////////////////////////////////////////
289
290