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//////////////////////////////////////////////////////////////////////////////
41///////////////////////////////////////////////////////////////////////////////
42// IMPLEMENTATION of inline methods.
43///////////////////////////////////////////////////////////////////////////////
49 // Helper class to choose the PlaneProbingNeighborhood class at compile-time
50 // (used in the constructor of PlaneProbingTetrahedronEstimator)
51 template < typename TPredicate, DGtal::ProbingMode mode >
52 struct PlaneProbingNeighborhoodSelector
54 static DGtal::PlaneProbingNeighborhood<TPredicate>*
55 select(TPredicate const&,
56 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const&,
57 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const&);
60 template < typename TPredicate >
61 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::H>
63 static DGtal::PlaneProbingNeighborhood<TPredicate>*
64 select(TPredicate const& aPredicate,
65 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
66 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
68 return new DGtal::PlaneProbingHNeighborhood<TPredicate>(aPredicate, aQ, aM);
72 template < typename TPredicate >
73 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::R>
75 static DGtal::PlaneProbingNeighborhood<TPredicate>*
76 select(TPredicate const& aPredicate,
77 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
78 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
80 return new DGtal::PlaneProbingRNeighborhood<TPredicate>(aPredicate, aQ, aM);
84 template < typename TPredicate >
85 struct PlaneProbingNeighborhoodSelector<TPredicate, DGtal::ProbingMode::R1>
87 static DGtal::PlaneProbingNeighborhood<TPredicate>*
88 select(TPredicate const& aPredicate,
89 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Point const& aQ,
90 typename DGtal::PlaneProbingNeighborhood<TPredicate>::Triangle const& aM)
92 return new DGtal::PlaneProbingR1Neighborhood<TPredicate>(aPredicate, aQ, aM);
99///////////////////////////////////////////////////////////////////////////////
100// ----------------------- Standard services ------------------------------
102// ------------------------------------------------------------------------
103template < typename TPredicate, DGtal::ProbingMode mode >
105DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
106PlaneProbingTetrahedronEstimator (Point const& aPoint, Triangle const& aM, Predicate const& aPredicate)
107 : myM(aM), myPredicate(aPredicate), myS(aM[0] + aM[1] + aM[2]), myQ(aPoint + myS)
109 myNeighborhood = DGtal::detail::PlaneProbingNeighborhoodSelector<TPredicate, mode>::select(myPredicate, myQ, myM);
112// ------------------------------------------------------------------------
113template < typename TPredicate, DGtal::ProbingMode mode >
115DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
116~PlaneProbingTetrahedronEstimator ()
118 delete myNeighborhood;
119 myNeighborhood = nullptr;
122///////////////////////////////////////////////////////////////////////////////
123// ----------------------- Plane probing services ------------------------------
125// ------------------------------------------------------------------------
126template < typename TPredicate, DGtal::ProbingMode mode >
128typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector const&
129DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::m (int aIndex) const
131 assert(aIndex == 0 || aIndex == 1 || aIndex == 2);
135// ------------------------------------------------------------------------
136template < typename TPredicate, DGtal::ProbingMode mode >
138typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point const&
139DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::q () const
144// ------------------------------------------------------------------------
145template < typename TPredicate, DGtal::ProbingMode mode >
147typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point
148DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getOrigin () const
150 return myQ - (myM[0] + myM[1] + myM[2]);
153// ------------------------------------------------------------------------
154template < typename TPredicate, DGtal::ProbingMode mode >
156typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Triangle
157DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::vertices () const
159 return { myQ - myM[0], myQ - myM[1], myQ - myM[2] };
162// ------------------------------------------------------------------------
163template < typename TPredicate, DGtal::ProbingMode mode >
165std::pair<typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector,
166 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector>
167DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getBasis () const
169 using DGtal::detail::squaredNorm;
171 Vector u = myM[1] - myM[0],
176 if (squaredNorm(u) < squaredNorm(v)) {
177 if (squaredNorm(u) < squaredNorm(w)) {
178 if (squaredNorm(-w) < squaredNorm(v)) {
179 return std::make_pair(u, -w);
181 return std::make_pair(u, v);
184 if (squaredNorm(-v) < squaredNorm(u)) {
185 return std::make_pair(w, -v);
187 return std::make_pair(w, u);
191 if (squaredNorm(v) < squaredNorm(w)) {
192 if (squaredNorm(-u) < squaredNorm(w)) {
193 return std::make_pair(v, -u);
195 return std::make_pair(v, w);
198 if (squaredNorm(-v) < squaredNorm(u)) {
199 return std::make_pair(w, -v);
201 return std::make_pair(w, u);
207// ------------------------------------------------------------------------
208template < typename TPredicate, DGtal::ProbingMode mode >
211DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isReduced () const
213 auto basis = getBasis();
214 return DGtal::detail::isBasisReduced(basis.first, basis.second);
217// ------------------------------------------------------------------------
218template < typename TPredicate, DGtal::ProbingMode mode >
220typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector
221DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getNormal () const
223 auto basis = getBasis();
224 return basis.first.crossProduct(basis.second);
227// ------------------------------------------------------------------------
228template < typename TPredicate, DGtal::ProbingMode mode >
230std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
231DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::advance (std::vector<PointOnProbingRay> const& aNeighbors)
233 myNeighborhood->setNeighbors(aNeighbors);
234 HexagonState state = hexagonState();
236 if (state == HexagonState::Planar)
238 UpdateOperation op = myNeighborhood->closestCandidate();
244 return { false, {} };
247// ------------------------------------------------------------------------
248template < typename TPredicate, DGtal::ProbingMode mode >
250std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
251DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::advance ()
256// ------------------------------------------------------------------------
257template < typename TPredicate, DGtal::ProbingMode mode >
259typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
260DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute (std::vector<PointOnProbingRay> const& aNeighbors)
262 while (advance(aNeighbors).first) {}
267// ------------------------------------------------------------------------
268template < typename TPredicate, DGtal::ProbingMode mode >
270typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
271DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute ()
276// ------------------------------------------------------------------------
277template < typename TPredicate, DGtal::ProbingMode mode >
279typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Neighborhood::HexagonState
280DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::hexagonState () const
282 return myNeighborhood->hexagonState();
285// ------------------------------------------------------------------------
286template < typename TPredicate, DGtal::ProbingMode mode >
289DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::translateQ (Vector const& aTranslation)
294// ------------------------------------------------------------------------
295template < typename TPredicate, DGtal::ProbingMode mode >
298DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::translateQ ()
300 UpdateOperation const& lastOp = myOperations[myOperations.size() - 1];
301 Point translation = lastOp.coeffs[1] * myM[lastOp.sigma[1]] + lastOp.coeffs[2] * myM[lastOp.sigma[2]];
303 translateQ(translation);
306///////////////////////////////////////////////////////////////////////////////
307// ------------------------- Internals ------------------------------------
309// ------------------------------------------------------------------------
310template < typename TPredicate, DGtal::ProbingMode mode >
313DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::applyOperation (UpdateOperation const& aOp)
315 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]];
318// ------------------------------------------------------------------------
319template < typename TPredicate, DGtal::ProbingMode mode >
322DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::update (UpdateOperation const& aOp)
325 myOperations.push_back(aOp);
328///////////////////////////////////////////////////////////////////////////////
329// Interface - public :
331// ------------------------------------------------------------------------
332template <typename TPredicate, DGtal::ProbingMode mode>
335DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::selfDisplay ( std::ostream & out ) const
337 out << "[PlaneProbingTetrahedronEstimator]";
340// ------------------------------------------------------------------------
341template <typename TPredicate, DGtal::ProbingMode mode>
344DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isValid() const
346 return ( isUnimodular() && isProjectedInside() );
349// ------------------------------------------------------------------------
350template <typename TPredicate, DGtal::ProbingMode mode>
353DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isInside() const
355 Triangle v = vertices();
356 for (int i = 0; i < 3; ++i) {
357 if (! myPredicate(v[i])) {
364// ------------------------------------------------------------------------
365template <typename TPredicate, DGtal::ProbingMode mode>
368DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isUnimodular() const
370 Point nest = getNormal();
371 for (int i = 0; i < 3; ++i) {
372 if (myM[i].dot(nest) != 1) {
379// ------------------------------------------------------------------------
380template < typename TPredicate, DGtal::ProbingMode mode >
383DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isProjectedInside (Triangle const& aTriangle) const
385 Triangle vec = { myQ - aTriangle[0], myQ - aTriangle[1], myQ - aTriangle[2] };
387 Point s = myM[0] + myM[1] + myM[2];
388 std::array<bool, 3> res, res_not;
389 for (int i = 0; i < 3; ++i)
391 int im1 = (i - 1 + 3) % 3;
392 Point nk = vec[im1].crossProduct(vec[i]);
394 res[i] = (nk.dot(-s) <= 0);
395 res_not[i] = !res[i];
398 return (res[0] && res[1] && res[2]) || (res_not[0] && res_not[1] && res_not[2]);
401// ------------------------------------------------------------------------
402template < typename TPredicate, DGtal::ProbingMode mode >
405DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isProjectedInside () const
407 return isProjectedInside(vertices());
411///////////////////////////////////////////////////////////////////////////////
412// Implementation of inline functions //
414template <typename TPredicate, DGtal::ProbingMode mode>
417DGtal::operator<< ( std::ostream & out,
418 const PlaneProbingTetrahedronEstimator<TPredicate, mode> & object )
420 object.selfDisplay( out );
425///////////////////////////////////////////////////////////////////////////////