DGtal  1.4.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 inline
74 typename DGtal::PlaneProbingNeighborhood<TPredicate>::PointOnProbingRay
75 DGtal::PlaneProbingNeighborhood<TPredicate>::closestPointInList (std::vector<PointOnProbingRay> const& aPoints) const
76 {
77  const auto N = aPoints.size();
78  if (N == 1) {
79  return aPoints[0];
80  }
81 
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];
86  }
87  }
88 
89  return minPoint;
90 }
91 
92 // ------------------------------------------------------------------------
93 template < typename TPredicate >
94 inline
95 typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
96 DGtal::PlaneProbingNeighborhood<TPredicate>::classify (std::array<bool, 6> const& aState) const
97 {
98  int inside = 0;
99  for (int i = 0; i < 6; ++i)
100  {
101  if (aState[i])
102  {
103  inside++;
104  }
105  }
106 
107  if (inside == 0)
108  {
109  // All the points are not in the plane => algorithm stops
110  return HexagonState::Empty;
111  }
112  else if (inside == 1)
113  {
114  // Only one point in the plane => algorithm continues
115  return HexagonState::Planar;
116  }
117  else if (inside == 2 || inside == 3)
118  {
119  // two points aligned with q in the plane => algorithm stops
120  for (int i = 0; i < 3; ++i)
121  {
122  if (aState[i] && aState[(i + 3) % 6])
123  {
124  return HexagonState::NonConvex;
125  }
126  }
127 
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)
131  {
132  if (aState[i] && !aState[(i + 1) % 6] && aState[(i + 2) % 6])
133  {
134  return HexagonState::NonPlanar;
135  }
136  }
137 
138  return HexagonState::Planar;
139  }
140 
141  // Strictly more than 3 points in the plane => algorithm stops
142  return HexagonState::NonConvex;
143 }
144 
145 // ------------------------------------------------------------------------
146 template < typename TPredicate >
147 inline
148 void
149 DGtal::PlaneProbingNeighborhood<TPredicate>::
150 setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
151 {
152  myNeighbors = aNeighbors;
153 }
154 
155 // ------------------------------------------------------------------------
156 template < typename TPredicate >
157 inline
158 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
159 DGtal::PlaneProbingNeighborhood<TPredicate>::
160 closestCandidate ()
161 {
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());
165 
166  PointOnProbingRay closest = closestPointInList(myCandidates);
167 
168  return getOperation(closest);
169 }
170 
171 // ------------------------------------------------------------------------
172 template < typename TPredicate >
173 inline
174 typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
175 DGtal::PlaneProbingNeighborhood<TPredicate>::
176 getOperation (PointOnProbingRay const& aClosest) const
177 {
178  return {
179  aClosest.sigma(),
180  { 1, -1, -aClosest.index() },
181  };
182 }
183 
184 // ------------------------------------------------------------------------
185 template < typename TPredicate >
186 inline
187 bool
188 DGtal::PlaneProbingNeighborhood<TPredicate>::isNeighbor (PointOnProbingRay const& r) const
189 {
190  if (myNeighbors.empty())
191  {
192  return true;
193  }
194 
195  return std::find(myNeighbors.begin(), myNeighbors.end(), r) != myNeighbors.end();
196 }
197 
198 // ------------------------------------------------------------------------
199 template < typename TPredicate >
200 inline
201 bool
202 DGtal::PlaneProbingNeighborhood<TPredicate>::
203 isSmallest (Point const& aX, Point const& aY) const
204 {
205  Integer zero = DGtal::NumberTraits<Integer>::ZERO;
206 
207  std::array<Point, 5> ps;
208  for (int i = 0; i < 3; ++i)
209  {
210  ps[i] = -myM[i];
211  }
212  ps[3] = aX;
213  ps[4] = aY;
214 
215  Integer res = DGtal::detail::distToSphere(ps);
216  if (res == zero) {
217  return aY < aX;
218  } else if (res < zero) {
219  return true;
220  } else {
221  return false;
222  }
223 }
224 
225 // ------------------------------------------------------------------------
226 template < typename TPredicate >
227 inline
228 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229 DGtal::PlaneProbingNeighborhood<TPredicate>::
230 relativePoint (PointOnProbingRay const& aRay) const
231 {
232  return -myM[aRay.sigma(0)] + myM[aRay.sigma(1)] + myM[aRay.sigma(2)] * aRay.index();
233 }
234 
235 // ------------------------------------------------------------------------
236 template < typename TPredicate >
237 inline
238 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
239 DGtal::PlaneProbingNeighborhood<TPredicate>::
240 absolutePoint (PointOnProbingRay const& aRay) const
241 {
242  return myQ + relativePoint(aRay);
243 }
244 
245 
246 ///////////////////////////////////////////////////////////////////////////////
247 // Interface - public :
248 
249 /**
250  * Writes/Displays the object on an output stream.
251  * @param out the output stream where the object is written.
252  */
253 template <typename TPredicate>
254 inline
255 void
256 DGtal::PlaneProbingNeighborhood<TPredicate>::selfDisplay ( std::ostream & out ) const
257 {
258  out << "[PlaneProbingNeighborhood]";
259 }
260 
261 /**
262  * Checks the validity/consistency of the object.
263  * @return 'true' if the object is valid, 'false' otherwise.
264  */
265 template <typename TPredicate>
266 inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
267 {
268  return true;
269 }
270 
271 
272 
273 ///////////////////////////////////////////////////////////////////////////////
274 // Implementation of inline functions //
275 
276 template <typename TPredicate>
277 inline
278 std::ostream&
279 DGtal::operator<< ( std::ostream & out,
280  const PlaneProbingNeighborhood<TPredicate> & object )
281 {
282  object.selfDisplay( out );
283  return out;
284 }
285 
286 // //
287 ///////////////////////////////////////////////////////////////////////////////
288 
289