34 #include "DGtal/kernel/NumberTraits.h"
35 #include "DGtal/kernel/sets/CDigitalSet.h"
46 template <
typename TSpace,
typename TSequence>
52 template <
typename TSpace,
typename TSequence>
58 template <
typename TSpace,
typename TSequence>
66 template <
typename TSpace,
typename TSequence>
77 template <
typename TSpace,
typename TSequence>
83 return myVertices.begin();
86 template <
typename TSpace,
typename TSequence>
92 return myVertices.end();
95 template <
typename TSpace,
typename TSequence>
101 return myVertices.begin();
104 template <
typename TSpace,
typename TSequence>
110 return myVertices.end();
113 template <
typename TSpace,
typename TSequence>
119 return myVertices.empty();
122 template <
typename TSpace,
typename TSequence>
128 return myVertices.size();
131 template <
typename TSpace,
typename TSequence>
137 return myVertices.max_size();
140 template <
typename TSpace,
typename TSequence>
149 template <
typename TSpace,
typename TSequence>
155 return myVertices.erase( it );
158 template <
typename TSpace,
typename TSequence>
168 template <
typename TSpace,
typename TSequence>
178 template <
typename TSpace,
typename TSequence>
186 Point supremum = *it;
187 for ( ++it; it != it_end; ++it )
189 infimum = infimum.inf( *it );
190 supremum = supremum.sup( *it );
192 return Domain( infimum, supremum );
195 template <
typename TSpace,
typename TSequence>
203 while ( it != it_end )
208 while ( ( it != it_end ) && ( _A == *it ) )
212 if ( ( size() > 1 ) && ( * begin() == *it_prev ) )
216 template <
typename TSpace,
typename TSequence>
222 return myVertices.insert( pos, K );
225 template <
typename TSpace,
typename TSequence>
231 myVertices.push_back( K );
234 template <
typename TSpace,
typename TSequence>
240 myVertices.push_front( K );
243 template <
typename TSpace,
typename TSequence>
249 myVertices.push_back( K );
252 template <
typename TSpace,
typename TSequence>
258 myVertices.push_front( K );
261 template <
typename TSpace,
typename TSequence>
271 while ( it_next != it_end )
273 _a += _ic.crossProduct( *it, *it_next );
274 it = it_next; ++it_next;
276 _a += _ic.crossProduct( *it, *(begin()) );
280 template <
typename TSpace,
typename TSequence>
287 return centroid( _a );
290 template <
typename TSpace,
typename TSequence>
303 _den = 3 * twice_area;
305 while ( it_next != it_end )
307 _ic.getCrossProduct( _c, *it, *it_next );
311 it = it_next; ++it_next;
313 _ic.getCrossProduct( _c, *it, *it_begin );
314 _B = *it + *it_begin;
321 for ( ; it != it_end; ++it )
327 return Point3I( _A[ 0 ], _A[ 1 ], _den );
330 template <
typename TSpace,
typename TSequence>
340 while ( it_next != it_end )
343 ic().getGcd( _g, _N[ 0 ], _N[ 1 ] );
345 it = it_next; ++it_next;
347 _N = *it - *(begin());
348 ic().getGcd( _g, _N[ 0 ], _N[ 1 ] );
353 template <
typename TSpace,
typename TSequence>
359 _c1 = numberBoundaryPoints();
362 ASSERT( ic().isZero( _c % 2 ) );
366 template <
typename TSpace,
typename TSequence>
378 it_next_is_outside = it_next_is_inside = it_end;
381 bool visibility_begin_vtx;
382 bool visibility_prev_vtx;
385 if ( ( visibility_begin_vtx = hs( *it++ ) ) ) ++nbWithin;
386 visibility_prev_vtx = visibility_begin_vtx;
387 for ( ; it != it_end; ++it, ++nb )
389 if ( ( visibility_vtx = hs( *it ) ) ) ++nbWithin;
390 if ( visibility_vtx != visibility_prev_vtx )
392 if ( visibility_prev_vtx ) it_next_is_outside = it_prev;
393 else it_next_is_inside = it_prev;
395 visibility_prev_vtx = visibility_vtx;
398 if ( visibility_vtx != visibility_begin_vtx )
400 if ( visibility_vtx ) it_next_is_outside = it_prev;
401 else it_next_is_inside = it_prev;
403 ASSERT( ( nbWithin == 0 ) || ( nbWithin == size() )
404 || ( ( it_next_is_outside != it_end ) && ( it_next_is_inside != it_end )
405 && ( it_next_is_inside != it_next_is_outside ) ) );
406 return std::make_pair( nbWithin, nb );
410 template <
typename TSpace,
typename TSequence>
418 SizeCouple nbs = findCut( it_next_is_outside, it_next_is_inside, hs );
421 if ( nbs.first == nbs.second ) {
return false; }
426 HalfSpace hs1 = halfSpace( it_next_is_outside );
427 HalfSpace hs3 = halfSpace( it_next_is_inside );
429 _A1 = *it_next_is_outside;
430 ++it_next_is_outside;
431 if ( it_next_is_outside == end() ) it_next_is_outside = begin();
432 _B1 = *it_next_is_outside;
433 _B2 = *it_next_is_inside;
435 if ( it_next_is_inside == end() ) it_next_is_inside = begin();
436 _A2 = *it_next_is_inside;
439 while ( it_next_is_outside != it_next_is_inside )
441 it_next_is_outside = erase( it_next_is_outside );
442 if ( it_next_is_outside == end() ) it_next_is_outside = begin();
447 std::insert_iterator<ClockwiseVertexSequence> itOut
448 = std::inserter<ClockwiseVertexSequence,Iterator>( myVertices, it_next_is_outside );
449 computeConvexHullBorder( itOut, _A1, _A2, hs1, hs, hs3 );
456 _a = ( hs.
c - hs.
N.dot( _A1 ) ) / ( hs.
N.dot( _v ) );
458 insertBefore( it_next_is_outside, _A1 );
464 template <
typename TSpace,
typename TSequence>
470 Point A( *it ); ++it;
471 if ( it == end() ) it = begin();
472 Point B( *it ); ++it;
473 if ( it == end() ) it = begin();
474 _N[ 0 ] = A[ 1 ] - B[ 1 ];
475 _N[ 1 ] = B[ 0 ] - A[ 0 ];
476 _ic.getDotProduct( _c, _N, A );
477 _ic.getDotProduct( _c1, _N, *it );
484 _ic.getGcd( _g, _N[ 0 ], _N[ 1 ] );
486 return HalfSpace( _N, _ic.floorDiv( _c, _g) );
489 template <
typename TSpace,
typename TSequence>
495 _N[ 0 ] = A[ 1 ] - B[ 1 ];
496 _N[ 1 ] = B[ 0 ] - A[ 0 ];
497 _ic.getDotProduct( _c, _N, A );
498 _ic.getDotProduct( _c1, _N, inP );
505 _ic.getGcd( _g, _N[ 0 ], _N[ 1 ] );
507 return HalfSpace( _N, _ic.floorDiv( _c, _g) );
520 template <
typename TSpace,
typename TSequence>
521 template <
typename DigitalSet>
530 typedef typename DigitalSet::Iterator DigitalSetIterator;
533 if ( empty() )
return;
538 aSet.insert( *begin() );
547 Vector orthN( -hs.
N[ 1 ], hs.
N[ 0 ] );
548 HalfSpace hs_orth( orthN, _ic.dotProduct( orthN, *it_vtx ) );
549 if ( ! hs_orth( *it_vtx2 ) ) hs_orth.
negate();
551 Vector orthN2( -hs2.
N[ 1 ], hs2.
N[ 0 ] );
552 HalfSpace hs2_orth( orthN2, _ic.dotProduct( orthN2, *it_vtx2 ) );
553 if ( ! hs2_orth( *it_vtx ) ) hs2_orth.
negate();
555 for ( DomainConstIterator it = aSet.domain().begin(),
556 it_end = aSet.domain().end(); it != it_end; ++it )
557 if ( hs( *it ) ) aSet.insert( *it );
558 for ( DigitalSetIterator it_set = aSet.begin(), it_set_end = aSet.end();
559 it_set != it_set_end; )
561 DigitalSetIterator it_cur = it_set; ++it_set;
562 if ( ! ( hs_orth( *it_cur )
564 && hs2_orth( *it_cur ) ) )
565 aSet.erase( it_cur );
573 for ( DomainConstIterator it = aSet.domain().begin(),
574 it_end = aSet.domain().end(); it != it_end; ++it )
575 if ( hs( *it ) ) aSet.insert( *it );
577 for ( ; it_vtx != it_vtx_end; ++it_vtx )
579 hs = halfSpace( it_vtx );
580 for ( DigitalSetIterator it_set = aSet.begin(), it_set_end = aSet.end();
581 it_set != it_set_end; )
583 DigitalSetIterator it_cur = it_set; ++it_set;
584 if ( ! hs( *it_cur ) ) aSet.erase( it_cur );
589 template <
typename TSpace,
typename TSequence>
600 bool exactIntersection;
606 _ic.getCoefficientIntersection( _fl, _ce,
607 inPt, _DV, hs2.
N, hs2.
c );
612 _ic.getDotProduct( _a, inPt, hs2.
N );
635 exactIntersection =
true;
641 _ic.getValidBezout( v, inPt, _DV, hs1.
N, hs1.
c, hs2.
N, hs2.
c,
true );
642 exactIntersection =
false;
645 #ifdef DEBUG_LatticePolytope2D
646 std::cerr <<
"[CIP::getFirstPointsOfHull] in=" << inPt
647 <<
" out=" << outPt <<
" v=" << v << std::endl;
648 #endif //DEBUG_LatticePolytope2D
651 ASSERT( hs2( inPt ) );
652 ASSERT( ( exactIntersection && hs2( outPt ) ) || ( ! exactIntersection && ! hs2( outPt ) ) );
653 return exactIntersection;
676 template <
typename TSpace,
typename TSequence>
680 std::vector<Point> & outPts,
685 ASSERT( hs2.
N != hs3.
N );
702 #ifdef DEBUG_LatticePolytope2D
703 std::cerr <<
"[CIP::getAllPointsOfHull] A=" << _A
704 <<
" B=" << _B <<
" v= " << _v << std::endl;
705 #endif // DEBUG_LatticePolytope2D
708 _ic.getCoefficientIntersection( _fl, _ce,
709 _B, _v, hs2.
N, hs2.
c );
710 _u = _B; _u += _v *_fl;
714 outPts.push_back( _B );
715 #ifdef DEBUG_LatticePolytope2D
716 std::cerr <<
"[CIP::getAllPointsOfHull] add B=" << _B << std::endl;
717 #endif // ifdef DEBUG_LatticePolytope2D
721 _ic.getCoefficientIntersection( _fl, _ce,
722 _B, _v, hs3.
N, hs3.
c );
724 outPts.push_back( _B );
725 #ifdef DEBUG_LatticePolytope2D
726 std::cerr <<
"[CIP::getAllPointsOfHull] add B=" << _B << std::endl;
727 #endif //ifdef DEBUG_LatticePolytope2D
734 _ic.getCoefficientIntersection( _fl, _ce,
735 _A, _v, hs2.
N, hs2.
c );
736 _u = _A; _u += _v *_fl;
740 inPts.push_back( _A );
741 #ifdef DEBUG_LatticePolytope2D
742 std::cerr <<
"[CIP::getAllPointsOfHull] add A=" << _A << std::endl;
743 #endif //ifdef DEBUG_LatticePolytope2D
747 _ic.getCoefficientIntersection( _fl, _ce,
748 _A, _v, hs3.
N, hs3.
c );
750 inPts.push_back( _A );
751 #ifdef DEBUG_LatticePolytope2D
752 std::cerr <<
"[CIP::getAllPointsOfHull] add A=" << _A << std::endl;
753 #endif //ifdef DEBUG_LatticePolytope2D
763 _ic.getValidBezout( _v, _A, _u, hs2.
N, hs2.
c, hs2.
N, hs2.
c,
false );
773 outPts.push_back( _A );
775 inPts.push_back( _B );
800 template <
typename TSpace,
typename TSequence>
801 template <
typename OutputIterator>
805 ( OutputIterator itOut,
806 const Point & pointRefC1,
807 const Point & pointRefC3,
813 bool exactIntersection;
818 _inPts[ 0 ] = pointRefC1;
822 exactIntersection = getFirstPointsOfHull( _v, _inPts[ 0 ], _outPts[ 0 ],
824 if ( ! exactIntersection )
827 getAllPointsOfHull( _inPts, _outPts, _v, hs2, hs3 );
830 for(
Size i = 0; i < _inPts.size(); ++i )
831 *itOut++ = _inPts[ i ];
838 _inPts[0] = pointRefC3;
841 exactIntersection = getFirstPointsOfHull( _v, _inPts[ 0 ], _outPts[ 0 ],
843 if ( ! exactIntersection )
846 getAllPointsOfHull( _inPts, _outPts, _v, hs2, hs1 );
849 for(
Size i = _inPts.size(); i != 0; --i )
851 *itOut++ = _inPts[ i - 1 ];
865 template <
typename TSpace,
typename TSequence>
870 out <<
"[LatticePolytope2D #Vertices=" << size() <<
"]";
877 template <
typename TSpace,
typename TSequence>
885 template <
typename TSpace,
typename TSequence>
891 return "LatticePolytope2D";
899 template <
typename TSpace,
typename TSequence>
905 object.selfDisplay( out );