DGtal  1.5.beta
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 
39 template < typename TPredicate >
40 const 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 // ------------------------------------------------------------------------
55 template < typename TPredicate >
56 inline
57 DGtal::PlaneProbingNeighborhood<TPredicate>::
58 PlaneProbingNeighborhood(Predicate const& aPredicate, Point const& aQ, Triangle const& aM)
59  : myPredicate(aPredicate), myQ(aQ), myM(aM)
60 {}
61 
62 // ------------------------------------------------------------------------
63 template < typename TPredicate >
64 inline
65 DGtal::PlaneProbingNeighborhood<TPredicate>::~PlaneProbingNeighborhood()
66 {}
67 
68 ///////////////////////////////////////////////////////////////////////////////
69 // ----------------------- Plane Probing services ------------------------------
70 
71 // ------------------------------------------------------------------------
72 template < typename TPredicate >
73 template < typename TPointAdapter >
74 inline
75 TPointAdapter
76 DGtal::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 // ------------------------------------------------------------------------
92 template < typename TPredicate >
93 inline
94 typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
95 DGtal::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 // ------------------------------------------------------------------------
145 template < typename TPredicate >
146 inline
147 void
148 DGtal::PlaneProbingNeighborhood<TPredicate>::
149 setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
150 {
151  myNeighbors = aNeighbors;
152 }
153 
154 // ------------------------------------------------------------------------
155 template < typename TPredicate >
156 inline
157 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
158 DGtal::PlaneProbingNeighborhood<TPredicate>::
159 closestCandidate ()
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 // ------------------------------------------------------------------------
171 template < typename TPredicate >
172 inline
173 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
174 DGtal::PlaneProbingNeighborhood<TPredicate>::
175 getOperation (PointOnProbingRay const& aClosest) const
176 {
177  return {
178  aClosest.sigma(),
179  { 1, -1, -aClosest.position() },
180  };
181 }
182 
183 // ------------------------------------------------------------------------
184 template < typename TPredicate >
185 inline
186 bool
187 DGtal::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 // ------------------------------------------------------------------------
198 template < typename TPredicate >
199 inline
200 bool
201 DGtal::PlaneProbingNeighborhood<TPredicate>::
202 isSmallest (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 // ------------------------------------------------------------------------
225 template < typename TPredicate >
226 template < typename TPointAdapter >
227 inline
228 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229 DGtal::PlaneProbingNeighborhood<TPredicate>::
230 relativePoint (TPointAdapter const& aPoint) const
231 {
232  return aPoint.relativePoint(myM);
233 }
234 
235 // ------------------------------------------------------------------------
236 template < typename TPredicate >
237 template < typename TPointAdapter >
238 inline
239 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
240 DGtal::PlaneProbingNeighborhood<TPredicate>::
241 absolutePoint (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  */
254 template <typename TPredicate>
255 inline
256 void
257 DGtal::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  */
266 template <typename TPredicate>
267 inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
268 {
269  return true;
270 }
271 
272 
273 
274 ///////////////////////////////////////////////////////////////////////////////
275 // Implementation of inline functions //
276 
277 template <typename TPredicate>
278 inline
279 std::ostream&
280 DGtal::operator<< ( std::ostream & out,
281  const PlaneProbingNeighborhood<TPredicate> & object )
282 {
283  object.selfDisplay( out );
284  return out;
285 }
286 
287 // //
288 ///////////////////////////////////////////////////////////////////////////////
289 
290