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 // ------------------------------------------------------------------------
103 template < typename TPredicate, DGtal::ProbingMode mode >
105 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
106 PlaneProbingTetrahedronEstimator (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 // ------------------------------------------------------------------------
113 template < typename TPredicate, DGtal::ProbingMode mode >
115 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::
116 ~PlaneProbingTetrahedronEstimator ()
118 delete myNeighborhood;
119 myNeighborhood = nullptr;
122 ///////////////////////////////////////////////////////////////////////////////
123 // ----------------------- Plane probing services ------------------------------
125 // ------------------------------------------------------------------------
126 template < typename TPredicate, DGtal::ProbingMode mode >
128 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector const&
129 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::m (int aIndex) const
131 assert(aIndex == 0 || aIndex == 1 || aIndex == 2);
135 // ------------------------------------------------------------------------
136 template < typename TPredicate, DGtal::ProbingMode mode >
138 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point const&
139 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::q () const
144 // ------------------------------------------------------------------------
145 template < typename TPredicate, DGtal::ProbingMode mode >
147 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Point
148 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getOrigin () const
150 return myQ - (myM[0] + myM[1] + myM[2]);
153 // ------------------------------------------------------------------------
154 template < typename TPredicate, DGtal::ProbingMode mode >
156 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Triangle
157 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::vertices () const
159 return { myQ - myM[0], myQ - myM[1], myQ - myM[2] };
162 // ------------------------------------------------------------------------
163 template < typename TPredicate, DGtal::ProbingMode mode >
165 std::pair<typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector,
166 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector>
167 DGtal::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 // ------------------------------------------------------------------------
208 template < typename TPredicate, DGtal::ProbingMode mode >
211 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isReduced () const
213 auto basis = getBasis();
214 return DGtal::detail::isBasisReduced(basis.first, basis.second);
217 // ------------------------------------------------------------------------
218 template < typename TPredicate, DGtal::ProbingMode mode >
220 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Vector
221 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::getNormal () const
223 auto basis = getBasis();
224 return basis.first.crossProduct(basis.second);
227 // ------------------------------------------------------------------------
228 template < typename TPredicate, DGtal::ProbingMode mode >
230 std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
231 DGtal::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 // ------------------------------------------------------------------------
248 template < typename TPredicate, DGtal::ProbingMode mode >
250 std::pair<bool, typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::UpdateOperation>
251 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::advance ()
256 // ------------------------------------------------------------------------
257 template < typename TPredicate, DGtal::ProbingMode mode >
259 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
260 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute (std::vector<PointOnProbingRay> const& aNeighbors)
262 while (advance(aNeighbors).first) {}
267 // ------------------------------------------------------------------------
268 template < typename TPredicate, DGtal::ProbingMode mode >
270 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Quantity
271 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::compute ()
276 // ------------------------------------------------------------------------
277 template < typename TPredicate, DGtal::ProbingMode mode >
279 typename DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::Neighborhood::HexagonState
280 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::hexagonState () const
282 return myNeighborhood->hexagonState();
285 // ------------------------------------------------------------------------
286 template < typename TPredicate, DGtal::ProbingMode mode >
289 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::translateQ (Vector const& aTranslation)
294 // ------------------------------------------------------------------------
295 template < typename TPredicate, DGtal::ProbingMode mode >
298 DGtal::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 // ------------------------------------------------------------------------
310 template < typename TPredicate, DGtal::ProbingMode mode >
313 DGtal::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 // ------------------------------------------------------------------------
319 template < typename TPredicate, DGtal::ProbingMode mode >
322 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::update (UpdateOperation const& aOp)
325 myOperations.push_back(aOp);
328 ///////////////////////////////////////////////////////////////////////////////
329 // Interface - public :
331 // ------------------------------------------------------------------------
332 template <typename TPredicate, DGtal::ProbingMode mode>
335 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::selfDisplay ( std::ostream & out ) const
337 out << "[PlaneProbingTetrahedronEstimator]";
340 // ------------------------------------------------------------------------
341 template <typename TPredicate, DGtal::ProbingMode mode>
344 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isValid() const
346 return ( isUnimodular() && isProjectedInside() );
349 // ------------------------------------------------------------------------
350 template <typename TPredicate, DGtal::ProbingMode mode>
353 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isInside() const
355 Triangle v = vertices();
356 for (int i = 0; i < 3; ++i) {
357 if (! myPredicate(v[i])) {
364 // ------------------------------------------------------------------------
365 template <typename TPredicate, DGtal::ProbingMode mode>
368 DGtal::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 // ------------------------------------------------------------------------
380 template < typename TPredicate, DGtal::ProbingMode mode >
383 DGtal::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 // ------------------------------------------------------------------------
402 template < typename TPredicate, DGtal::ProbingMode mode >
405 DGtal::PlaneProbingTetrahedronEstimator<TPredicate, mode>::isProjectedInside () const
407 return isProjectedInside(vertices());
411 ///////////////////////////////////////////////////////////////////////////////
412 // Implementation of inline functions //
414 template <typename TPredicate, DGtal::ProbingMode mode>
417 DGtal::operator<< ( std::ostream & out,
418 const PlaneProbingTetrahedronEstimator<TPredicate, mode> & object )
420 object.selfDisplay( out );
425 ///////////////////////////////////////////////////////////////////////////////