DGtal 1.3.0
Loading...
Searching...
No Matches
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 >
73inline
74typename DGtal::PlaneProbingNeighborhood<TPredicate>::PointOnProbingRay
75DGtal::PlaneProbingNeighborhood<TPredicate>::closestPointInList (std::vector<PointOnProbingRay> const& aPoints) const
76{
77 int N = aPoints.size();
78 if (N == 1) {
79 return aPoints[0];
80 }
81
82 PointOnProbingRay minPoint = aPoints[N-1];
83 for (int k = 0; k < N-1; ++k) {
84 if (isSmallest(relativePoint(minPoint), relativePoint(aPoints[k]))) {
85 minPoint = aPoints[k];
86 }
87 }
88
89 return minPoint;
90}
91
92// ------------------------------------------------------------------------
93template < typename TPredicate >
94inline
95typename DGtal::PlaneProbingNeighborhood<TPredicate>::HexagonState
96DGtal::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// ------------------------------------------------------------------------
146template < typename TPredicate >
147inline
148void
149DGtal::PlaneProbingNeighborhood<TPredicate>::
150setNeighbors (std::vector<PointOnProbingRay> const& aNeighbors)
151{
152 myNeighbors = aNeighbors;
153}
154
155// ------------------------------------------------------------------------
156template < typename TPredicate >
157inline
158typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
159DGtal::PlaneProbingNeighborhood<TPredicate>::
160closestCandidate ()
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// ------------------------------------------------------------------------
172template < typename TPredicate >
173inline
174typename DGtal::PlaneProbingNeighborhood<TPredicate>::UpdateOperation
175DGtal::PlaneProbingNeighborhood<TPredicate>::
176getOperation (PointOnProbingRay const& aClosest) const
177{
178 return {
179 aClosest.sigma(),
180 { 1, -1, -aClosest.index() },
181 };
182}
183
184// ------------------------------------------------------------------------
185template < typename TPredicate >
186inline
187bool
188DGtal::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// ------------------------------------------------------------------------
199template < typename TPredicate >
200inline
201bool
202DGtal::PlaneProbingNeighborhood<TPredicate>::
203isSmallest (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// ------------------------------------------------------------------------
226template < typename TPredicate >
227inline
228typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
229DGtal::PlaneProbingNeighborhood<TPredicate>::
230relativePoint (PointOnProbingRay const& aRay) const
231{
232 return -myM[aRay.sigma(0)] + myM[aRay.sigma(1)] + myM[aRay.sigma(2)] * aRay.index();
233}
234
235// ------------------------------------------------------------------------
236template < typename TPredicate >
237inline
238typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point
239DGtal::PlaneProbingNeighborhood<TPredicate>::
240absolutePoint (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 */
253template <typename TPredicate>
254inline
255void
256DGtal::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 */
265template <typename TPredicate>
266inline bool DGtal::PlaneProbingNeighborhood<TPredicate>::isValid() const
267{
268 return true;
269}
270
271
272
273///////////////////////////////////////////////////////////////////////////////
274// Implementation of inline functions //
275
276template <typename TPredicate>
277inline
278std::ostream&
279DGtal::operator<< ( std::ostream & out,
280 const PlaneProbingNeighborhood<TPredicate> & object )
281{
282 object.selfDisplay( out );
283 return out;
284}
285
286// //
287///////////////////////////////////////////////////////////////////////////////
288
289