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 bool check_duplicate_constraints )
82 : myValidEdgeConstraints( valid_edge_constraints )
84 init( domain, itB, itE,
85 valid_edge_constraints, check_duplicate_constraints );
88 //-----------------------------------------------------------------------------
89 template <typename TSpace>
90 template <typename HalfSpaceIterator>
92 DGtal::BoundedLatticePolytope<TSpace>::
93 init( const Domain& domain,
94 HalfSpaceIterator itB, HalfSpaceIterator itE,
95 bool valid_edge_constraints,
96 bool check_duplicate_constraints )
99 myValidEdgeConstraints = valid_edge_constraints;
100 const Dimension d = dimension;
101 const Point lo = domain.lowerBound();
102 const Point hi = domain.upperBound();
103 D = Domain( lo, hi );
104 // Add constraints related to sup/inf in x.
105 for ( Dimension s = 0; s < d; ++s )
107 Vector z = Vector::zero;
108 z[ s ] = NumberTraits<Integer>::ONE;
110 B.push_back( hi[ s ] );
111 z[ s ] = -NumberTraits<Integer>::ONE;
113 B.push_back( -lo[ s ] );
116 if ( check_duplicate_constraints )
118 // Add other halfplanes
119 for ( auto it = itB; it != itE; ++it )
121 // Checks that is not inside.
122 const auto a = it->N;
123 const auto b = it->c;
124 const auto itAE = A.begin()+2*d;
125 const auto itF = std::find( A.begin(), itAE , a );
134 const auto k = itF - A.begin();
135 B[ k ] = std::min( B[ k ], b );
140 { // Add other halfplanes
141 for ( auto it = itB; it != itE; ++it )
143 A.push_back( it->N );
144 B.push_back( it->c );
148 I = std::vector<bool>( nb_hp, true ); // inequalities are large
151 //-----------------------------------------------------------------------------
152 template <typename TSpace>
154 DGtal::BoundedLatticePolytope<TSpace>::
155 internalInitFromTriangle3D( Point a, Point b, Point c )
160 Vector n = detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
161 crossProduct( ab, bc );
162 if ( n == Vector::zero ) { clear(); return false; }
164 B.push_back( a.dot( A.back() ) );
167 B.push_back( a.dot( A.back() ) );
168 I = std::vector<bool>( B.size(), true ); // inequalities are large
169 std::vector<Point> pts = { a, b, c };
170 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
171 addEdgeConstraint( *this, 0, 1, pts );
172 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
173 addEdgeConstraint( *this, 1, 2, pts );
174 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
175 addEdgeConstraint( *this, 2, 0, pts );
179 //-----------------------------------------------------------------------------
180 template <typename TSpace>
182 DGtal::BoundedLatticePolytope<TSpace>::
183 internalInitFromSegment3D( Point a, Point b )
186 if ( ab == Vector::zero ) return true; // domain and constraints already computed
188 for ( Dimension k = 0; k < 3; ++k )
190 const auto t = Vector::base( k );
191 Vector w = detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::
192 crossProduct( ab, t );
193 if ( w == Vector::zero ) continue;
195 B.push_back( a.dot( w ) );
196 A.push_back( -1 * w );
197 B.push_back( a.dot( A.back() ) );
200 I = std::vector<bool>( 2 * 3 + nb, true ); // inequalities are large
204 //-----------------------------------------------------------------------------
205 template <typename TSpace>
207 DGtal::BoundedLatticePolytope<TSpace>::
208 internalInitFromSegment2D( Point a, Point b )
211 if ( ab == Vector::zero ) return true; // domain and constraints already computed
212 Vector n( -ab[ 1 ], ab[ 0 ] );
214 B.push_back( a.dot( n ) );
215 A.push_back( -1 * n );
216 B.push_back( a.dot( A.back() ) );
217 I = std::vector<bool>( 2*2+2, true ); // inequalities are large
221 //-----------------------------------------------------------------------------
222 template <typename TSpace>
223 template <typename PointIterator>
225 DGtal::BoundedLatticePolytope<TSpace>::
226 init( PointIterator itB, PointIterator itE )
228 typedef SimpleMatrix<Integer,dimension,dimension> Matrix;
230 const Dimension d = dimension;
231 std::vector<Point> pts;
232 for ( ; itB != itE; ++itB ) pts.push_back( *itB );
235 for ( Dimension s = 1; s < pts.size(); ++s )
237 lo = lo.inf( pts[ s ] );
238 hi = hi.sup( pts[ s ] );
240 // Add constraints related to sup/inf in x.
241 for ( Dimension s = 0; s < d; ++s )
243 Vector z = Vector::zero;
244 z[ s ] = NumberTraits<Integer>::ONE;
246 B.push_back( hi[ s ] );
247 z[ s ] = -NumberTraits<Integer>::ONE;
249 B.push_back( -lo[ s ] );
251 D = Domain( lo, hi );
252 if ( pts.size() != d+1 )
253 { // Some degenerated cases are taken into account.
254 myValidEdgeConstraints = true;
256 if ( pts.size() == 3 )
257 return internalInitFromTriangle3D( pts[ 0 ], pts[ 1 ], pts[ 2 ] );
258 else if ( pts.size() == 2 )
259 return internalInitFromSegment3D( pts[ 0 ], pts[ 1 ] );
260 } else if ( d == 2 ) {
261 if ( pts.size() == 2 )
262 return internalInitFromSegment2D( pts[ 0 ], pts[ 1 ] );
264 I = std::vector<bool>( 2*2, true ); // inequalities are large
265 if ( pts.size() == 1 ) return true;
269 // Build Matrix A and Vector b through cofactors
270 I = std::vector<bool>( 3*d+1, true ); // inequalities are large
273 for ( Dimension s = 0; s <= d; ++s )
275 // Build matrix v composed of p_i and vectors p_k - p_i for i and k != p
277 Dimension p = (s+1) % (d+1);
278 for ( Dimension j = 0; j < d; ++j )
279 V.setComponent( 0, j, pts[ p ][ j ] - pts[ s ][ j ] );
280 for ( Dimension k = 1; k < d; ++k )
282 Dimension l = (p+k) % (d+1);
283 for ( Dimension j = 0; j < d; ++j )
284 V.setComponent( k, j, pts[ l ][ j ] - pts[ p ][ j ] );
293 // Form vector [b, 0, ..., 0]
294 Vector z = Vector::zero;
296 a = V.cofactor().transpose() * z;
297 b += a.dot( pts[ s ] );
299 if ( a.dot( pts[ s ] ) > b ) { a *= (Integer) -1; b *= (Integer) -1; }
303 myValidEdgeConstraints = true;
304 if ( dimension >= 3 )
305 { // One should add edges
306 for ( unsigned int i = 0; i < pts.size(); ++i )
307 for ( unsigned int j = i+1; j < pts.size(); ++j ) {
308 detail::BoundedLatticePolytopeSpecializer< dimension, Integer >::addEdgeConstraint
309 ( *this, i, j, pts );
311 if ( dimension >= 4 )
312 { // Not implemented yet
313 myValidEdgeConstraints = false;
320 //-----------------------------------------------------------------------------
321 template <typename TSpace>
322 DGtal::BoundedLatticePolytope<TSpace>
323 DGtal::BoundedLatticePolytope<TSpace>::
324 interiorPolytope() const
326 BoundedLatticePolytope P( *this );
327 for ( auto it = P.I.begin(), itE = P.I.end(); it != itE; ++it )
332 //-----------------------------------------------------------------------------
333 template <typename TSpace>
335 DGtal::BoundedLatticePolytope<TSpace>::
336 cut( Dimension k, bool pos, Integer b, bool large )
338 ASSERT( k < dimension );
339 auto i = 2*k + (pos ? 0 : 1);
340 B[ i ] = std::min( B[ i ], b );
342 Point L = D.lowerBound();
343 Point U = D.upperBound();
344 if ( pos ) U[ k ] = B[ i ];
345 else L[ k ] = -B[ i ];
350 //-----------------------------------------------------------------------------
351 template <typename TSpace>
353 DGtal::BoundedLatticePolytope<TSpace>::
354 cut( const Vector& a, Integer b, bool large, bool valid_edge_constraint )
356 // Checks that is not inside.
357 auto it = std::find( A.begin(), A.end(), a );
362 I.push_back( large );
363 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
368 auto k = it - A.begin();
369 B[ k ] = std::min( B[ k ], b );
371 myValidEdgeConstraints = myValidEdgeConstraints && valid_edge_constraint; // a cut might invalidate an edge constraint
375 //-----------------------------------------------------------------------------
376 template <typename TSpace>
378 DGtal::BoundedLatticePolytope<TSpace>::
379 cut( const HalfSpace& hs, bool large, bool valid_edge_constraint )
383 return cut( a, b, large, valid_edge_constraint );
386 //-----------------------------------------------------------------------------
387 template <typename TSpace>
389 DGtal::BoundedLatticePolytope<TSpace>::
390 swap( BoundedLatticePolytope & other )
395 std::swap( D, other.D );
396 std::swap( myValidEdgeConstraints, other.myValidEdgeConstraints );
399 //-----------------------------------------------------------------------------
400 template <typename TSpace>
402 DGtal::BoundedLatticePolytope<TSpace>::
403 isInside( const Point& p ) const
406 for ( Dimension i = 0; 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 isDomainPointInside( const Point& p ) const
424 for ( Dimension i = 2*dimension; i < A.size(); ++i )
428 ? A[ i ].dot( p ) <= B[ i ]
429 : A[ i ].dot( p ) < B[ i ];
430 if ( ! in_half_space ) return false;
435 //-----------------------------------------------------------------------------
436 template <typename TSpace>
438 DGtal::BoundedLatticePolytope<TSpace>::
439 isInterior( const Point& p ) const
442 for ( Dimension i = 0; i < A.size(); ++i )
444 bool in_half_space = A[ i ].dot( p ) < B[ i ];
445 if ( ! in_half_space ) return false;
450 //-----------------------------------------------------------------------------
451 template <typename TSpace>
453 DGtal::BoundedLatticePolytope<TSpace>::
454 isBoundary( const Point& p ) const
457 bool is_boundary = false;
458 for ( Dimension i = 0; i < A.size(); ++i )
460 auto Ai_dot_p = A[ i ].dot( p );
461 if ( Ai_dot_p == B[ i ] ) is_boundary = true;
462 if ( Ai_dot_p > B[ i ] ) return false;
467 //-----------------------------------------------------------------------------
468 template <typename TSpace>
469 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
470 DGtal::BoundedLatticePolytope<TSpace>::
471 operator*=( Integer t )
473 for ( Integer& b : B ) b *= t;
474 D = Domain( D.lowerBound() * t, D.upperBound() * t );
478 //-----------------------------------------------------------------------------
479 template <typename TSpace>
480 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
481 DGtal::BoundedLatticePolytope<TSpace>::
482 operator+=( UnitSegment s )
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 ];
489 Vector z = Vector::zero;
490 z[ s.k ] = NumberTraits<Integer>::ONE;
491 D = Domain( D.lowerBound(), D.upperBound() + z );
495 //-----------------------------------------------------------------------------
496 template <typename TSpace>
497 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
498 DGtal::BoundedLatticePolytope<TSpace>::
499 operator+=( LeftStrictUnitSegment s )
501 I[ 2*s.k + 1 ] = false;
502 for ( Dimension i = 0; i < A.size(); ++i )
504 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO )
505 B[ i ] += A[ i ][ s.k ];
506 if ( A[ i ][ s.k ] < NumberTraits<Integer>::ZERO )
509 Vector z = Vector::zero;
510 z[ s.k ] = NumberTraits<Integer>::ONE;
511 D = Domain( D.lowerBound() + z, D.upperBound() + z );
515 //-----------------------------------------------------------------------------
516 template <typename TSpace>
517 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
518 DGtal::BoundedLatticePolytope<TSpace>::
519 operator+=( RightStrictUnitSegment s )
522 for ( Dimension i = 0; i < A.size(); ++i )
524 if ( A[ i ][ s.k ] > NumberTraits<Integer>::ZERO ) {
525 B[ i ] += A[ i ][ s.k ];
529 Vector z = Vector::zero;
530 z[ s.k ] = NumberTraits<Integer>::ONE;
534 //-----------------------------------------------------------------------------
535 template <typename TSpace>
536 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
537 DGtal::BoundedLatticePolytope<TSpace>::
538 operator+=( UnitCell c )
540 for ( Dimension i = 0; i < c.dims.size(); ++i )
541 *this += UnitSegment( c.dims[ i ] );
545 //-----------------------------------------------------------------------------
546 template <typename TSpace>
547 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
548 DGtal::BoundedLatticePolytope<TSpace>::
549 operator+=( RightStrictUnitCell c )
551 for ( Dimension i = 0; i < c.dims.size(); ++i )
552 *this += RightStrictUnitSegment( c.dims[ i ] );
556 //-----------------------------------------------------------------------------
557 template <typename TSpace>
558 typename DGtal::BoundedLatticePolytope<TSpace>::Self&
559 DGtal::BoundedLatticePolytope<TSpace>::
560 operator+=( LeftStrictUnitCell c )
562 for ( Dimension i = 0; i < c.dims.size(); ++i )
563 *this += LeftStrictUnitSegment( c.dims[ i ] );
567 //-----------------------------------------------------------------------------
568 template <typename TSpace>
569 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
570 DGtal::BoundedLatticePolytope<TSpace>::
574 for ( const Point & p : D )
575 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
579 //-----------------------------------------------------------------------------
580 template <typename TSpace>
581 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
582 DGtal::BoundedLatticePolytope<TSpace>::
583 countInterior() const
586 for ( const Point & p : D )
587 nb += isInterior( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
590 //-----------------------------------------------------------------------------
591 template <typename TSpace>
592 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
593 DGtal::BoundedLatticePolytope<TSpace>::
594 countBoundary() const
597 for ( const Point & p : D )
598 nb += isBoundary( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
601 //-----------------------------------------------------------------------------
602 template <typename TSpace>
603 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
604 DGtal::BoundedLatticePolytope<TSpace>::
605 countWithin( Point lo, Point hi ) const
608 Domain D1( lo.sup( D.lowerBound() ), hi.inf( D.upperBound() ) );
609 for ( const Point & p : D1 )
610 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
613 //-----------------------------------------------------------------------------
614 template <typename TSpace>
615 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
616 DGtal::BoundedLatticePolytope<TSpace>::
617 countUpTo( Integer max) const
620 for ( const Point & p : D ) {
621 nb += isDomainPointInside( p ) ? NumberTraits<Integer>::ONE : NumberTraits<Integer>::ZERO;
622 if ( nb >= max ) return max;
626 //-----------------------------------------------------------------------------
627 template <typename TSpace>
629 DGtal::BoundedLatticePolytope<TSpace>::
630 getPoints( std::vector<Point>& pts ) const
633 for ( const Point & p : D )
634 if ( isDomainPointInside( p ) ) pts.push_back( p );
636 //-----------------------------------------------------------------------------
637 template <typename TSpace>
638 template <typename PointSet>
640 DGtal::BoundedLatticePolytope<TSpace>::
641 insertPoints( PointSet& pts_set ) const
643 for ( const Point & p : D )
644 if ( isDomainPointInside( p ) ) pts_set.insert( p );
646 //-----------------------------------------------------------------------------
647 template <typename TSpace>
649 DGtal::BoundedLatticePolytope<TSpace>::
650 getInteriorPoints( std::vector<Point>& pts ) const
653 for ( const Point & p : D )
654 if ( isInterior( p ) ) pts.push_back( p );
656 //-----------------------------------------------------------------------------
657 template <typename TSpace>
659 DGtal::BoundedLatticePolytope<TSpace>::
660 getBoundaryPoints( std::vector<Point>& pts ) const
663 for ( const Point & p : D )
664 if ( isBoundary( p ) ) pts.push_back( p );
667 //-----------------------------------------------------------------------------
668 template <typename TSpace>
669 const typename DGtal::BoundedLatticePolytope<TSpace>::Domain&
670 DGtal::BoundedLatticePolytope<TSpace>::getDomain() const
675 //-----------------------------------------------------------------------------
676 template <typename TSpace>
678 DGtal::BoundedLatticePolytope<TSpace>::nbHalfSpaces() const
683 //-----------------------------------------------------------------------------
684 template <typename TSpace>
685 const typename DGtal::BoundedLatticePolytope<TSpace>::Vector&
686 DGtal::BoundedLatticePolytope<TSpace>::getA( unsigned int i ) const
688 ASSERT( i < nbHalfSpaces() );
692 //-----------------------------------------------------------------------------
693 template <typename TSpace>
694 typename DGtal::BoundedLatticePolytope<TSpace>::Integer
695 DGtal::BoundedLatticePolytope<TSpace>::getB( unsigned int i ) const
697 ASSERT( i < nbHalfSpaces() );
701 //-----------------------------------------------------------------------------
702 template <typename TSpace>
704 DGtal::BoundedLatticePolytope<TSpace>::isLarge( unsigned int i ) const
706 ASSERT( i < nbHalfSpaces() );
710 //-----------------------------------------------------------------------------
711 template <typename TSpace>
712 const typename DGtal::BoundedLatticePolytope<TSpace>::InequalityMatrix&
713 DGtal::BoundedLatticePolytope<TSpace>::getA() const
718 //-----------------------------------------------------------------------------
719 template <typename TSpace>
720 const typename DGtal::BoundedLatticePolytope<TSpace>::InequalityVector&
721 DGtal::BoundedLatticePolytope<TSpace>::getB() const
726 //-----------------------------------------------------------------------------
727 template <typename TSpace>
728 const std::vector<bool>&
729 DGtal::BoundedLatticePolytope<TSpace>::getI() const
734 //-----------------------------------------------------------------------------
735 template <typename TSpace>
737 DGtal::BoundedLatticePolytope<TSpace>::canBeSummed() const
739 return myValidEdgeConstraints;
742 ///////////////////////////////////////////////////////////////////////////////
743 // Interface - public :
746 * Writes/Displays the object on an output stream.
747 * @param out the output stream where the object is written.
749 template <typename TSpace>
752 DGtal::BoundedLatticePolytope<TSpace>::selfDisplay ( std::ostream & out ) const
754 out << "[BoundedLatticePolytope<" << Space::dimension << "> A.rows=" << A.size()
755 << " valid_edge_constraints=" << myValidEdgeConstraints
757 for ( Dimension i = 0; i < A.size(); ++i )
760 for ( Dimension j = 0; j < dimension; ++j )
761 out << " " << A[ i ][ j ];
762 out << " ] . x <= " << B[ i ] << std::endl;
767 * Checks the validity/consistency of the object.
768 * @return 'true' if the object is valid, 'false' otherwise.
770 template <typename TSpace>
773 DGtal::BoundedLatticePolytope<TSpace>::isValid() const
775 return ! D.isEmpty();
777 //-----------------------------------------------------------------------------
778 template <typename TSpace>
781 DGtal::BoundedLatticePolytope<TSpace>::className
784 return "BoundedLatticePolytope";
789 ///////////////////////////////////////////////////////////////////////////////
790 // Implementation of inline functions //
792 //-----------------------------------------------------------------------------
793 template <typename TSpace>
796 DGtal::operator<< ( std::ostream & out,
797 const BoundedLatticePolytope<TSpace> & object )
799 object.selfDisplay( out );
802 //-----------------------------------------------------------------------------
803 template <typename TSpace>
804 DGtal::BoundedLatticePolytope<TSpace>
805 DGtal::operator* ( typename BoundedLatticePolytope<TSpace>::Integer t,
806 const BoundedLatticePolytope<TSpace> & P )
808 BoundedLatticePolytope<TSpace> Q = P;
812 //-----------------------------------------------------------------------------
813 template <typename TSpace>
814 DGtal::BoundedLatticePolytope<TSpace>
815 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
816 typename BoundedLatticePolytope<TSpace>::UnitSegment s )
818 BoundedLatticePolytope<TSpace> Q = P;
822 //-----------------------------------------------------------------------------
823 template <typename TSpace>
824 DGtal::BoundedLatticePolytope<TSpace>
825 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
826 typename BoundedLatticePolytope<TSpace>::UnitCell c )
828 BoundedLatticePolytope<TSpace> Q = P;
832 //-----------------------------------------------------------------------------
833 template <typename TSpace>
834 DGtal::BoundedLatticePolytope<TSpace>
835 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
836 typename BoundedLatticePolytope<TSpace>::RightStrictUnitSegment s )
838 BoundedLatticePolytope<TSpace> Q = P;
842 //-----------------------------------------------------------------------------
843 template <typename TSpace>
844 DGtal::BoundedLatticePolytope<TSpace>
845 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
846 typename BoundedLatticePolytope<TSpace>::RightStrictUnitCell c )
848 BoundedLatticePolytope<TSpace> Q = P;
852 //-----------------------------------------------------------------------------
853 template <typename TSpace>
854 DGtal::BoundedLatticePolytope<TSpace>
855 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
856 typename BoundedLatticePolytope<TSpace>::LeftStrictUnitSegment s )
858 BoundedLatticePolytope<TSpace> Q = P;
862 //-----------------------------------------------------------------------------
863 template <typename TSpace>
864 DGtal::BoundedLatticePolytope<TSpace>
865 DGtal::operator+ ( const BoundedLatticePolytope<TSpace> & P,
866 typename BoundedLatticePolytope<TSpace>::LeftStrictUnitCell c )
868 BoundedLatticePolytope<TSpace> Q = P;
874 ///////////////////////////////////////////////////////////////////////////////