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 PlaneProbingTetrahedronEstimator.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
35 #include "DGtal/geometry/helpers/PlaneProbingEstimatorHelper.h"
36 #include "DGtal/geometry/surfaces/estimation/PlaneProbingHNeighborhood.h"
37 #include "DGtal/geometry/surfaces/estimation/PlaneProbingRNeighborhood.h"
38 #include "DGtal/geometry/surfaces/estimation/PlaneProbingR1Neighborhood.h"
39 #include "DGtal/geometry/surfaces/estimation/PlaneProbingLNeighborhood.h"
40 //////////////////////////////////////////////////////////////////////////////
42 ///////////////////////////////////////////////////////////////////////////////
43 // IMPLEMENTATION of inline methods.
44 ///////////////////////////////////////////////////////////////////////////////
50 // Helper class to choose the PlaneProbingNeighborhood class at compile-time
51 // (used in the constructor of PlaneProbingTetrahedronEstimator)
52 template < typename TPredicate, DGtal::ProbingMode mode >
53 struct PlaneProbingNeighborhoodSelector
55 static DGtal::PlaneProbingNeighborhood<TPredicate>*
56 select(TPredicate const&,
57 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const&,
58 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const&);
61 template < typename TPredicate >
62 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::H>
64 static DGtal::PlaneProbingNeighborhood<TPredicate>*
65 select(TPredicate const& aPredicate,
66 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
67 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
69 return new DGtal::PlaneProbingHNeighborhood<TPredicate>(aPredicate, aQ, aM);
73 template < typename TPredicate >
74 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::R>
76 static DGtal::PlaneProbingNeighborhood<TPredicate>*
77 select(TPredicate const& aPredicate,
78 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
79 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
81 return new DGtal::PlaneProbingRNeighborhood<TPredicate>(aPredicate, aQ, aM);
85 template < typename TPredicate >
86 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::R1>
88 static DGtal::PlaneProbingNeighborhood<TPredicate>*
89 select(TPredicate const& aPredicate,
90 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
91 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
93 return new DGtal::PlaneProbingR1Neighborhood<TPredicate>(aPredicate, aQ, aM);
97 template < typename TPredicate >
98 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::L>
100 static DGtal::PlaneProbingNeighborhood<TPredicate>*
101 select(TPredicate const& aPredicate,
102 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
103 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
105 return new DGtal::PlaneProbingLNeighborhood<TPredicate>(aPredicate, aQ, aM);
109 } // namespace detail
112 ///////////////////////////////////////////////////////////////////////////////
113 // ----------------------- Standard services ------------------------------
115 // ------------------------------------------------------------------------
116 template < typename TPredicate, DGtal::ProbingMode mode >
118 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
119 PlaneProbingTetrahedronEstimator (Point const& aPoint, Triangle const& aM, Predicate const& aPredicate)
120 : myM(aM), myPredicate(aPredicate), myS(aM[0] + aM[1] + aM[2]), myQ(aPoint + myS)
122 myNeighborhood = DGtal::detail::PlaneProbingNeighborhoodSelector<TPredicate, mode>::select(myPredicate, myQ, myM);
125 // ------------------------------------------------------------------------
126 template < typename TPredicate, DGtal::ProbingMode mode >
128 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
129 ~PlaneProbingTetrahedronEstimator ()
131 delete myNeighborhood;
132 myNeighborhood = nullptr;
135 ///////////////////////////////////////////////////////////////////////////////
136 // ----------------------- Plane probing services ------------------------------
138 // ------------------------------------------------------------------------
139 template < typename TPredicate, DGtal::ProbingMode mode >
141 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector const&
142 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::m (int aIndex) const
144 assert(aIndex == 0 || aIndex == 1 || aIndex == 2);
148 // ------------------------------------------------------------------------
149 template < typename TPredicate, DGtal::ProbingMode mode >
151 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point const&
152 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::q () const
157 // ------------------------------------------------------------------------
158 template < typename TPredicate, DGtal::ProbingMode mode >
160 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point
161 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getOrigin () const
163 return myQ - (myM[0] + myM[1] + myM[2]);
166 // ------------------------------------------------------------------------
167 template < typename TPredicate, DGtal::ProbingMode mode >
169 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Triangle
170 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::vertices () const
172 return { myQ - myM[0], myQ - myM[1], myQ - myM[2] };
175 // ------------------------------------------------------------------------
176 template < typename TPredicate, DGtal::ProbingMode mode >
178 std::pair<typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector,
179 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector>
180 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getBasis () const
182 using DGtal::detail::squaredNorm;
184 Vector u = myM[1] - myM[0],
189 if (squaredNorm(u) < squaredNorm(v)) {
190 if (squaredNorm(u) < squaredNorm(w)) {
191 if (squaredNorm(-w) < squaredNorm(v)) {
192 return std::make_pair(u, -w);
194 return std::make_pair(u, v);
197 if (squaredNorm(-v) < squaredNorm(u)) {
198 return std::make_pair(w, -v);
200 return std::make_pair(w, u);
204 if (squaredNorm(v) < squaredNorm(w)) {
205 if (squaredNorm(-u) < squaredNorm(w)) {
206 return std::make_pair(v, -u);
208 return std::make_pair(v, w);
211 if (squaredNorm(-v) < squaredNorm(u)) {
212 return std::make_pair(w, -v);
214 return std::make_pair(w, u);
220 // ------------------------------------------------------------------------
221 template < typename TPredicate, DGtal::ProbingMode mode >
224 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isReduced () const
226 auto basis = getBasis();
227 return DGtal::detail::isBasisReduced(basis.first, basis.second);
230 // ------------------------------------------------------------------------
231 template < typename TPredicate, DGtal::ProbingMode mode >
233 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector
234 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getNormal () const
236 auto basis = getBasis();
237 return basis.first.crossProduct(basis.second);
240 // ------------------------------------------------------------------------
241 template < typename TPredicate, DGtal::ProbingMode mode >
243 std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
244 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::advance (std::vector<PointOnProbingRay> const& aNeighbors)
246 myNeighborhood->setNeighbors(aNeighbors);
247 HexagonState state = hexagonState();
249 if (state == HexagonState::Planar)
251 UpdateOperation op = myNeighborhood->closestCandidate();
257 return { false, {} };
260 // ------------------------------------------------------------------------
261 template < typename TPredicate, DGtal::ProbingMode mode >
263 std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
264 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::advance ()
269 // ------------------------------------------------------------------------
270 template < typename TPredicate, DGtal::ProbingMode mode >
272 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
273 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute (std::vector<PointOnProbingRay> const& aNeighbors)
275 while (advance(aNeighbors).first) {}
280 // ------------------------------------------------------------------------
281 template < typename TPredicate, DGtal::ProbingMode mode >
283 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
284 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute ()
289 // ------------------------------------------------------------------------
290 template < typename TPredicate, DGtal::ProbingMode mode >
292 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Neighborhood::HexagonState
293 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::hexagonState () const
295 return myNeighborhood->hexagonState();
298 // ------------------------------------------------------------------------
299 template < typename TPredicate, DGtal::ProbingMode mode >
302 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::translateQ (Vector const& aTranslation)
307 // ------------------------------------------------------------------------
308 template < typename TPredicate, DGtal::ProbingMode mode >
311 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::translateQ ()
313 UpdateOperation const& lastOp = myOperations[myOperations.size() - 1];
314 Point translation = lastOp.coeffs[1] * myM[lastOp.sigma[1]] + lastOp.coeffs[2] * myM[lastOp.sigma[2]];
316 translateQ(translation);
319 ///////////////////////////////////////////////////////////////////////////////
320 // ------------------------- Internals ------------------------------------
322 // ------------------------------------------------------------------------
323 template < typename TPredicate, DGtal::ProbingMode mode >
326 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::applyOperation (UpdateOperation const& aOp)
328 myM[aOp.sigma[0]] = aOp.coeffs[0] * myM[aOp.sigma[0]] + aOp.coeffs[1] * myM[aOp.sigma[1]] + aOp.coeffs[2] * myM[aOp.sigma[2]];
331 // ------------------------------------------------------------------------
332 template < typename TPredicate, DGtal::ProbingMode mode >
335 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::update (UpdateOperation const& aOp)
338 myOperations.push_back(aOp);
341 ///////////////////////////////////////////////////////////////////////////////
342 // Interface - public :
344 // ------------------------------------------------------------------------
345 template <typename TPredicate, DGtal::ProbingMode mode>
348 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::selfDisplay ( std::ostream & out ) const
350 out << "[PlaneProbingTetrahedronEstimator]";
353 // ------------------------------------------------------------------------
354 template <typename TPredicate, DGtal::ProbingMode mode>
357 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isValid() const
359 return ( isUnimodular() && isProjectedInside() );
362 // ------------------------------------------------------------------------
363 template <typename TPredicate, DGtal::ProbingMode mode>
366 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isInside() const
368 Triangle v = vertices();
369 for (int i = 0; i < 3; ++i) {
370 if (! myPredicate(v[i])) {
377 // ------------------------------------------------------------------------
378 template <typename TPredicate, DGtal::ProbingMode mode>
381 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isUnimodular() const
383 Point nest = getNormal();
384 for (int i = 0; i < 3; ++i) {
385 if (myM[i].dot(nest) != 1) {
392 // ------------------------------------------------------------------------
393 template < typename TPredicate, DGtal::ProbingMode mode >
396 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isProjectedInside (Triangle const& aTriangle) const
398 Triangle vec = { myQ - aTriangle[0], myQ - aTriangle[1], myQ - aTriangle[2] };
400 Point s = myM[0] + myM[1] + myM[2];
401 std::array<bool, 3> res, res_not;
402 for (int i = 0; i < 3; ++i)
404 int im1 = (i - 1 + 3) % 3;
405 Point nk = vec[im1].crossProduct(vec[i]);
407 res[i] = (nk.dot(-s) <= 0);
408 res_not[i] = !res[i];
411 return (res[0] && res[1] && res[2]) || (res_not[0] && res_not[1] && res_not[2]);
414 // ------------------------------------------------------------------------
415 template < typename TPredicate, DGtal::ProbingMode mode >
418 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isProjectedInside () const
420 return isProjectedInside(vertices());
424 ///////////////////////////////////////////////////////////////////////////////
425 // Implementation of inline functions //
427 template <typename TPredicate, DGtal::ProbingMode mode>
430 DGtal::operator<< ( std::ostream & out,
431 const PlaneProbingTetrahedronEstimator<TPredicate, mode> & object )
433 object.selfDisplay( out );
438 ///////////////////////////////////////////////////////////////////////////////