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/>.
18 * @file BoundedLatticePolytope.ih
19 * @author Jacques-Olivier Lachaud (\c jacques-olivier.lachaud@univ-savoie.fr )
20 * Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
24 * Implementation of inline methods defined in BoundedLatticePolytope.h
26 * This file is part of the DGtal library.
30 //////////////////////////////////////////////////////////////////////////////
32 #include "DGtal/math/linalg/SimpleMatrix.h"
33 //////////////////////////////////////////////////////////////////////////////
35 ///////////////////////////////////////////////////////////////////////////////
36 // IMPLEMENTATION of inline methods.
37 ///////////////////////////////////////////////////////////////////////////////
39 ///////////////////////////////////////////////////////////////////////////////
40 // ----------------------- Standard services ------------------------------
42 //-----------------------------------------------------------------------------
43 template <typename TSpace>
45 DGtal::BoundedLatticePolytope<TSpace>::
51 myValidEdgeConstraints = false;
52 D = Domain( Point::zero, Point::zero );
55 //-----------------------------------------------------------------------------
56 template <typename TSpace>
57 DGtal::BoundedLatticePolytope<TSpace>::
58 BoundedLatticePolytope( std::initializer_list<Point> l )
60 myValidEdgeConstraints = false;
61 init( l.begin(), l.end() );
64 //-----------------------------------------------------------------------------
65 template <typename TSpace>
66 template <typename PointIterator>
67 DGtal::BoundedLatticePolytope<TSpace>::
68 BoundedLatticePolytope( PointIterator itB, PointIterator itE )
70 myValidEdgeConstraints = false;
74 //-----------------------------------------------------------------------------
75 template <typename TSpace>
76 template <typename HalfSpaceIterator>
77 DGtal::BoundedLatticePolytope<TSpace>::
78 BoundedLatticePolytope( const Domain& domain,
79 HalfSpaceIterator itB, HalfSpaceIterator itE,
80 bool valid_edge_constraints )
81 : myValidEdgeConstraints( valid_edge_constraints )
83 init( domain, itB, itE );
86 //-----------------------------------------------------------------------------
87 template <typename TSpace>
88 template <typename HalfSpaceIterator>
90 DGtal::BoundedLatticePolytope<TSpace>::
91 init( const Domain& domain,
92 HalfSpaceIterator itB, HalfSpaceIterator itE,
93 bool valid_edge_constraints )
96 myValidEdgeConstraints = valid_edge_constraints;
97 const Dimension d = dimension;
98 const Point lo = domain.lowerBound();
99 const Point hi = domain.upperBound();
100 D = Domain( lo, hi );
101 // Add constraints related to sup/inf in x.
102 for ( Dimension s = 0; s < d; ++s )
104 Vector z = Vector::zero;
105 z[ s ] = NumberTraits<Integer>::ONE;
107 B.push_back( hi[ s ] );
108 z[ s ] = -NumberTraits<Integer>::ONE;
110 B.push_back( -lo[ s ] );
112 // Add other halfplanes
114 for ( auto it = itB; itB != itE; ++it, ++nb_hp ) {
115 // Checks that is not inside.
118 auto itF = std::find( A.begin(), A.begin()+2*d, a );
119 if ( itF == A.end() )
126 auto k = itF - A.begin();
127 B[ k ] = std::min( B[ k ], b );
130 I = std::vector<bool>( 2 * d + nb_hp, true ); // inequalities are large
133 //-----------------------------------------------------------------------------
134 template <typename TSpace>
136 DGtal::BoundedLatticePolytope<TSpace>::
137 internalInitFromTriangle3D( Point a, Point b, Point c )
142 Vector n = detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
143 crossProduct( ab, bc );
144 if ( n == Vector::zero ) { clear(); return false; }
146 B.push_back( a.dot( A.back() ) );
149 B.push_back( a.dot( A.back() ) );
150 I = std::vector<bool>( B.size(), true ); // inequalities are large
151 std::vector<Point> pts = { a, b, c };
152 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
153 addEdgeConstraint( *this, 0, 1, pts );
154 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
155 addEdgeConstraint( *this, 1, 2, pts );
156 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
157 addEdgeConstraint( *this, 2, 0, pts );
161 //-----------------------------------------------------------------------------
162 template <typename TSpace>
164 DGtal::BoundedLatticePolytope<TSpace>::
165 internalInitFromSegment3D( Point a, Point b )
168 if ( ab == Vector::zero ) return true; // domain and constraints already computed
170 for ( Dimension k = 0; k < 3; ++k )
172 const auto t = Vector::base( k );
173 Vector w = detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
174 crossProduct( ab, t );
175 if ( w == Vector::zero ) continue;
177 B.push_back( a.dot( w ) );
178 A.push_back( -1 * w );
179 B.push_back( a.dot( A.back() ) );
182 I = std::vector<bool>( 2 * 3 + nb, true ); // inequalities are large
186 //-----------------------------------------------------------------------------
187 template <typename TSpace>
189 DGtal::BoundedLatticePolytope<TSpace>::
190 internalInitFromSegment2D( Point a, Point b )
193 if ( ab == Vector::zero ) return true; // domain and constraints already computed
194 Vector n( -ab[ 1 ], ab[ 0 ] );
196 B.push_back( a.dot( n ) );
197 A.push_back( -1 * n );
198 B.push_back( a.dot( A.back() ) );
199 I = std::vector<bool>( 2*2+2, true ); // inequalities are large
203 //-----------------------------------------------------------------------------
204 template <typename TSpace>
205 template <typename PointIterator>
207 DGtal::BoundedLatticePolytope<TSpace>::
208 init( PointIterator itB, PointIterator itE )
210 typedef SimpleMatrix<Integer,dimension,dimension> Matrix;
212 const Dimension d = dimension;
213 std::vector<Point> pts;
214 for ( ; itB != itE; ++itB ) pts.push_back( *itB );
217 for ( Dimension s = 1; s < pts.size(); ++s )
219 lo = lo.inf( pts[ s ] );
220 hi = hi.sup( pts[ s ] );
222 // Add constraints related to sup/inf in x.
223 for ( Dimension s = 0; s < d; ++s )
225 Vector z = Vector::zero;
226 z[ s ] = NumberTraits<Integer>::ONE;
228 B.push_back( hi[ s ] );
229 z[ s ] = -NumberTraits<Integer>::ONE;
231 B.push_back( -lo[ s ] );
233 D = Domain( lo, hi );
234 if ( pts.size() != d+1 )
235 { // Some degenerated cases are taken into account.
236 myValidEdgeConstraints = true;
238 if ( pts.size() == 3 )
239 return internalInitFromTriangle3D( pts[ 0 ], pts[ 1 ], pts[ 2 ] );
240 else if ( pts.size() == 2 )
241 return internalInitFromSegment3D( pts[ 0 ], pts[ 1 ] );
242 } else if ( d == 2 ) {
243 if ( pts.size() == 2 )
244 return internalInitFromSegment2D( pts[ 0 ], pts[ 1 ] );
246 I = std::vector<bool>( 2*2, true ); // inequalities are large
247 if ( pts.size() == 1 ) return true;
251 // Build Matrix A and Vector b through cofactors
252 I = std::vector<bool>( 3*d+1, true ); // inequalities are large
255 for ( Dimension s = 0; s <= d; ++s )
257 // Build matrix v composed of p_i and vectors p_k - p_i for i and k != p
259 Dimension p = (s+1) % (d+1);
260 for ( Dimension j = 0; j < d; ++j )
261 V.setComponent( 0, j, pts[ p ][ j ] - pts[ s ][ j ] );
262 for ( Dimension k = 1; k < d; ++k )
264 Dimension l = (p+k) % (d+1);
265 for ( Dimension j = 0; j < d; ++j )
266 V.setComponent( k, j, pts[ l ][ j ] - pts[ p ][ j ] );
275 // Form vector [b, 0, ..., 0]
276 Vector z = Vector::zero;
278 a = V.cofactor().transpose() * z;
279 b += a.dot( pts[ s ] );
281 if ( a.dot( pts[ s ] ) > b ) { a *= (Integer) -1; b *= (Integer) -1; }
285 myValidEdgeConstraints = true;
286 if ( dimension >= 3 )
287 { // One should add edges
288 for ( unsigned int i = 0; i < pts.size(); ++i )
289 for ( unsigned int j = i+1; j < pts.size(); ++j ) {
290 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::addEdgeConstraint
291 ( *this, i, j, pts );
293 if ( dimension >= 4 )
294 { // Not implemented yet
295 myValidEdgeConstraints = false;
302 //-----------------------------------------------------------------------------
303 template <typename TSpace>
304 DGtal::BoundedLatticePolytope<TSpace>
305 DGtal::BoundedLatticePolytope<TSpace>::
306 interiorPolytope() const
308 BoundedLatticePolytope P( *this );
309 for ( auto it = P.I.begin(), itE = P.I.end(); it != itE; ++it )
314 //-----------------------------------------------------------------------------
315 template <typename TSpace>
317 DGtal::BoundedLatticePolytope<TSpace>::
318 cut( Dimension k, bool pos, Integer b, bool large )
320 ASSERT( k < dimension );
321 auto i = 2*k + (pos ? 0 : 1);
322 B[ i ] = std::min( B[ i ], b );
324 Point L = D.lowerBound();
325 Point U = D.upperBound();
326 if ( pos ) U[ k ] = B[ i ];
327 else L[ k ] = -B[ i ];
332 //-----------------------------------------------------------------------------
333 template <typename TSpace>
335 DGtal::BoundedLatticePolytope<TSpace>::
336 cut( const Vector& a, Integer b, bool large, bool valid_edge_constraint )
338 // Checks that is not inside.
339 auto it = std::find( A.begin(), A.end(), a );
344 I.push_back( large );
345 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
350 auto k = it - A.begin();
351 B[ k ] = std::min( B[ k ], b );
353 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
357 //-----------------------------------------------------------------------------
358 template <typename TSpace>
360 DGtal::BoundedLatticePolytope<TSpace>::
361 cut( const HalfSpace& hs, bool large, bool valid_edge_constraint )
365 return cut( a, b, large, valid_edge_constraint );
368 //-----------------------------------------------------------------------------
369 template <typename TSpace>
371 DGtal::BoundedLatticePolytope<TSpace>::
372 swap( BoundedLatticePolytope & other )
377 std::swap( D, other.D );
378 std::swap( myValidEdgeConstraints, other.myValidEdgeConstraints );
381 //-----------------------------------------------------------------------------
382 template <typename TSpace>
384 DGtal::BoundedLatticePolytope<TSpace>::
385 isInside( const Point& p ) const
388 for ( Dimension i = 0; i < A.size(); ++i )
392 ? A[ i ].dot( p ) <= B[ i ]
393 : A[ i ].dot( p ) < B[ i ];
394 if ( ! in_half_space ) return false;
399 //-----------------------------------------------------------------------------
400 template <typename TSpace>
402 DGtal::BoundedLatticePolytope<TSpace>::
403 isDomainPointInside( const Point& p ) const
406 for ( Dimension i = 2*dimension; i < A.size(); ++i )
410 ? A[ i ].dot( p ) <= B[ i ]
411 : A[ i ].dot( p ) < B[ i ];
412 if ( ! in_half_space ) return false;
417 //-----------------------------------------------------------------------------
418 template <typename TSpace>
420 DGtal::BoundedLatticePolytope<TSpace>::
421 isInterior( const Point& p ) const
424 for ( Dimension i = 0; i < A.size(); ++i )
426 bool in_half_space = A[ i ].dot( p ) < B[ i ];
427 if ( ! in_half_space ) return false;
432 //-----------------------------------------------------------------------------
433 template <typename TSpace>
435 DGtal::BoundedLatticePolytope<TSpace>::
436 isBoundary( const Point& p ) const
439 bool is_boundary = false;
440 for ( Dimension i = 0; i < A.size(); ++i )
442 auto Ai_dot_p = A[ i ].dot( p );
443 if ( Ai_dot_p == B[ i ] ) is_boundary = true;
444 if ( Ai_dot_p > B[ i ] ) return false;
449 //-----------------------------------------------------------------------------
450 template <typename TSpace>
451 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
452 DGtal::BoundedLatticePolytope<TSpace>::
453 operator*=( Integer t )
455 for ( Integer& b : B ) b *= t;
456 D = Domain( D.lowerBound() * t, D.upperBound() * t );
460 //-----------------------------------------------------------------------------
461 template <typename TSpace>
462 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
463 DGtal::BoundedLatticePolytope<TSpace>::
464 operator+=( UnitSegment s )
466 for ( Dimension i = 0; i < A.size(); ++i )
468 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO )
469 B[ i ] += A[ i ][ s.k ];
471 Vector z = Vector::zero;
472 z[ s.k ] = NumberTraits<Integer>::ONE;
473 D = Domain( D.lowerBound(), D.upperBound() + z );
477 //-----------------------------------------------------------------------------
478 template <typename TSpace>
479 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
480 DGtal::BoundedLatticePolytope<TSpace>::
481 operator+=( LeftStrictUnitSegment s )
483 I[ 2*s.k + 1 ] = false;
484 for ( Dimension i = 0; i < A.size(); ++i )
486 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO )
487 B[ i ] += A[ i ][ s.k ];
488 if ( A[ i ][ s.k ] < NumberTraits<Integer>::ZERO )
491 Vector z = Vector::zero;
492 z[ s.k ] = NumberTraits<Integer>::ONE;
493 D = Domain( D.lowerBound() + z, D.upperBound() + z );
497 //-----------------------------------------------------------------------------
498 template <typename TSpace>
499 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
500 DGtal::BoundedLatticePolytope<TSpace>::
501 operator+=( RightStrictUnitSegment s )
504 for ( Dimension i = 0; i < A.size(); ++i )
506 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO ) {
507 B[ i ] += A[ i ][ s.k ];
511 Vector z = Vector::zero;
512 z[ s.k ] = NumberTraits<Integer>::ONE;
516 //-----------------------------------------------------------------------------
517 template <typename TSpace>
518 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
519 DGtal::BoundedLatticePolytope<TSpace>::
520 operator+=( UnitCell c )
522 for ( Dimension i = 0; i < c.dims.size(); ++i )
523 *this += UnitSegment( c.dims[ i ] );
527 //-----------------------------------------------------------------------------
528 template <typename TSpace>
529 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
530 DGtal::BoundedLatticePolytope<TSpace>::
531 operator+=( RightStrictUnitCell c )
533 for ( Dimension i = 0; i < c.dims.size(); ++i )
534 *this += RightStrictUnitSegment( c.dims[ i ] );
538 //-----------------------------------------------------------------------------
539 template <typename TSpace>
540 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
541 DGtal::BoundedLatticePolytope<TSpace>::
542 operator+=( LeftStrictUnitCell c )
544 for ( Dimension i = 0; i < c.dims.size(); ++i )
545 *this += LeftStrictUnitSegment( c.dims[ i ] );
549 //-----------------------------------------------------------------------------
550 template <typename TSpace>
551 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
552 DGtal::BoundedLatticePolytope<TSpace>::
556 for ( const Point & p : D )
557 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
561 //-----------------------------------------------------------------------------
562 template <typename TSpace>
563 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
564 DGtal::BoundedLatticePolytope<TSpace>::
565 countInterior() const
568 for ( const Point & p : D )
569 nb += isInterior( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
572 //-----------------------------------------------------------------------------
573 template <typename TSpace>
574 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
575 DGtal::BoundedLatticePolytope<TSpace>::
576 countBoundary() const
579 for ( const Point & p : D )
580 nb += isBoundary( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
583 //-----------------------------------------------------------------------------
584 template <typename TSpace>
585 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
586 DGtal::BoundedLatticePolytope<TSpace>::
587 countWithin( Point lo, Point hi ) const
590 Domain D1( lo.sup( D.lowerBound() ), hi.inf( D.upperBound() ) );
591 for ( const Point & p : D1 )
592 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
595 //-----------------------------------------------------------------------------
596 template <typename TSpace>
597 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
598 DGtal::BoundedLatticePolytope<TSpace>::
599 countUpTo( Integer max) const
602 for ( const Point & p : D ) {
603 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
604 if ( nb >= max ) return max;
608 //-----------------------------------------------------------------------------
609 template <typename TSpace>
611 DGtal::BoundedLatticePolytope<TSpace>::
612 getPoints( std::vector<Point>& pts ) const
615 for ( const Point & p : D )
616 if ( isDomainPointInside( p ) ) pts.push_back( p );
618 //-----------------------------------------------------------------------------
619 template <typename TSpace>
620 template <typename PointSet>
622 DGtal::BoundedLatticePolytope<TSpace>::
623 insertPoints( PointSet& pts_set ) const
625 for ( const Point & p : D )
626 if ( isDomainPointInside( p ) ) pts_set.insert( p );
628 //-----------------------------------------------------------------------------
629 template <typename TSpace>
631 DGtal::BoundedLatticePolytope<TSpace>::
632 getInteriorPoints( std::vector<Point>& pts ) const
635 for ( const Point & p : D )
636 if ( isInterior( p ) ) pts.push_back( p );
638 //-----------------------------------------------------------------------------
639 template <typename TSpace>
641 DGtal::BoundedLatticePolytope<TSpace>::
642 getBoundaryPoints( std::vector<Point>& pts ) const
645 for ( const Point & p : D )
646 if ( isBoundary( p ) ) pts.push_back( p );
649 //-----------------------------------------------------------------------------
650 template <typename TSpace>
651 const typename DGtal::BoundedLatticePolytope<TSpace>::Domain&
652 DGtal::BoundedLatticePolytope<TSpace>::getDomain() const
657 //-----------------------------------------------------------------------------
658 template <typename TSpace>
660 DGtal::BoundedLatticePolytope<TSpace>::nbHalfSpaces() const
665 //-----------------------------------------------------------------------------
666 template <typename TSpace>
667 const typename DGtal::BoundedLatticePolytope<TSpace>::Vector&
668 DGtal::BoundedLatticePolytope<TSpace>::getA( unsigned int i ) const
670 ASSERT( i < nbHalfSpaces() );
674 //-----------------------------------------------------------------------------
675 template <typename TSpace>
676 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
677 DGtal::BoundedLatticePolytope<TSpace>::getB( unsigned int i ) const
679 ASSERT( i < nbHalfSpaces() );
683 //-----------------------------------------------------------------------------
684 template <typename TSpace>
686 DGtal::BoundedLatticePolytope<TSpace>::isLarge( unsigned int i ) const
688 ASSERT( i < nbHalfSpaces() );
692 //-----------------------------------------------------------------------------
693 template <typename TSpace>
694 const typename DGtal::BoundedLatticePolytope<TSpace>::InequalityMatrix&
695 DGtal::BoundedLatticePolytope<TSpace>::getA() const
700 //-----------------------------------------------------------------------------
701 template <typename TSpace>
702 const typename DGtal::BoundedLatticePolytope<TSpace>::InequalityVector&
703 DGtal::BoundedLatticePolytope<TSpace>::getB() const
708 //-----------------------------------------------------------------------------
709 template <typename TSpace>
710 const std::vector<bool>&
711 DGtal::BoundedLatticePolytope<TSpace>::getI() const
716 //-----------------------------------------------------------------------------
717 template <typename TSpace>
719 DGtal::BoundedLatticePolytope<TSpace>::canBeSummed() const
721 return myValidEdgeConstraints;
724 ///////////////////////////////////////////////////////////////////////////////
725 // Interface - public :
728 * Writes/Displays the object on an output stream.
729 * @param out the output stream where the object is written.
731 template <typename TSpace>
734 DGtal::BoundedLatticePolytope<TSpace>::selfDisplay ( std::ostream & out ) const
736 out << "[BoundedLatticePolytope<" << Space::dimension << "> A.rows=" << A.size()
737 << " valid_edge_constraints=" << myValidEdgeConstraints
739 for ( Dimension i = 0; i < A.size(); ++i )
742 for ( Dimension j = 0; j < dimension; ++j )
743 out << " " << A[ i ][ j ];
744 out << " ] . x <= " << B[ i ] << std::endl;
749 * Checks the validity/consistency of the object.
750 * @return 'true' if the object is valid, 'false' otherwise.
752 template <typename TSpace>
755 DGtal::BoundedLatticePolytope<TSpace>::isValid() const
757 return ! D.isEmpty();
759 //-----------------------------------------------------------------------------
760 template <typename TSpace>
763 DGtal::BoundedLatticePolytope<TSpace>::className
766 return "BoundedLatticePolytope";
771 ///////////////////////////////////////////////////////////////////////////////
772 // Implementation of inline functions //
774 //-----------------------------------------------------------------------------
775 template <typename TSpace>
778 DGtal::operator<< ( std::ostream & out,
779 const BoundedLatticePolytope<TSpace> & object )
781 object.selfDisplay( out );
784 //-----------------------------------------------------------------------------
785 template <typename TSpace>
786 DGtal::BoundedLatticePolytope<TSpace>
787 DGtal::operator* ( typename BoundedLatticePolytope<TSpace>::Integer t,
788 const BoundedLatticePolytope<TSpace> & P )
790 BoundedLatticePolytope<TSpace> Q = P;
794 //-----------------------------------------------------------------------------
795 template <typename TSpace>
796 DGtal::BoundedLatticePolytope<TSpace>
797 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
798 typename BoundedLatticePolytope<TSpace>::UnitSegment s )
800 BoundedLatticePolytope<TSpace> Q = P;
804 //-----------------------------------------------------------------------------
805 template <typename TSpace>
806 DGtal::BoundedLatticePolytope<TSpace>
807 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
808 typename BoundedLatticePolytope<TSpace>::UnitCell c )
810 BoundedLatticePolytope<TSpace> Q = P;
814 //-----------------------------------------------------------------------------
815 template <typename TSpace>
816 DGtal::BoundedLatticePolytope<TSpace>
817 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
818 typename BoundedLatticePolytope<TSpace>::RightStrictUnitSegment s )
820 BoundedLatticePolytope<TSpace> Q = P;
824 //-----------------------------------------------------------------------------
825 template <typename TSpace>
826 DGtal::BoundedLatticePolytope<TSpace>
827 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
828 typename BoundedLatticePolytope<TSpace>::RightStrictUnitCell c )
830 BoundedLatticePolytope<TSpace> Q = P;
834 //-----------------------------------------------------------------------------
835 template <typename TSpace>
836 DGtal::BoundedLatticePolytope<TSpace>
837 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
838 typename BoundedLatticePolytope<TSpace>::LeftStrictUnitSegment s )
840 BoundedLatticePolytope<TSpace> Q = P;
844 //-----------------------------------------------------------------------------
845 template <typename TSpace>
846 DGtal::BoundedLatticePolytope<TSpace>
847 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
848 typename BoundedLatticePolytope<TSpace>::LeftStrictUnitCell c )
850 BoundedLatticePolytope<TSpace> Q = P;
856 ///////////////////////////////////////////////////////////////////////////////