/** * Algorithms that computes the alpha-shape * of a point set */ void alphaShape() { //Digitization of a disk of radius 8 Ball2D<Z2i::Space> ball(Z2i::Point(0,0), 8); Z2i::Domain domain(ball.getLowerBound(), ball.getUpperBound()); Z2i::DigitalSet digitalSet(domain); Shapes<Z2i::Domain>::euclideanShaper(digitalSet, ball); //Contour of the digital set Z2i::KSpace kspace; kspace.init(domain.lowerBound()-Z2i::Point(1,1), domain.upperBound()+Z2i::Point(1,1), true); typedef DigitalSetBoundary<Z2i::KSpace, Z2i::DigitalSet> DigitalSurfaceContainer; typedef DigitalSurface<DigitalSurfaceContainer> CustomDigitalSurface; DigitalSurfaceContainer digitalSurfaceContainer( kspace, digitalSet ); CustomDigitalSurface digitalSurface( digitalSurfaceContainer ); //Grid curve Z2i::Curve gridCurve; typedef DepthFirstVisitor<DigitalSurface<DigitalSurfaceContainer> > CustomVisitor; CustomVisitor visitor( digitalSurface, *digitalSurface.begin() ); while ( ! visitor.finished() ) { gridCurve.pushBack( visitor.current().first ); visitor.expand(); } //Point set defined as the set of (not duplicated) inner points typedef Z2i::Curve::InnerPointsRange PointRange; PointRange pointsRange = gridCurve.getInnerPointsRange(); vector<Z2i::Point> border; unique_copy( pointsRange.begin(), pointsRange.end(), back_inserter( border ) ); //namespace for hull functions using namespace functions::Hull2D; { //alpha = 0 trace.info() << " alpha == 0 " << endl; vector<Z2i::Point> res; //! [Hull2D-RadiusPredicateInf] typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; Functor functor(true, 1, 0); //alpha = 0; 1/alpha -> +inf typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); //! [Hull2D-RadiusPredicateInf] //! [Hull2D-ClosedGrahamScan] closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //! [Hull2D-ClosedGrahamScan] //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShape0.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShape0.png", Board2D::CairoPNG); #endif } { //alpha = 0 trace.info() << " alpha == 0 " << endl; vector<Z2i::Point> res; //comparator and functor typedef InHalfPlaneBySimple3x3Matrix<Z2i::Point, DGtal::int64_t> Functor; Functor functor; typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShape0bis.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShape0bis.png", Board2D::CairoPNG); #endif } //negative alpha shape { //alpha = -1 trace.info() << " alpha == -1 " << endl; vector<Z2i::Point> res; typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; //! [Hull2D-RadiusPredicateM1] Functor functor(false, 1, 1); //1/alpha = -sqrt(1/1) = -1 //! [Hull2D-RadiusPredicateM1] typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShapeM1.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShapeM1.png", Board2D::CairoPNG); #endif } { //alpha = -sqrt(5) trace.info() << " alpha == -sqrt(5) " << endl; vector<Z2i::Point> res; typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; //! [Hull2D-RadiusPredicateMsqrt5] Functor functor(false, 5, 1); //1/alpha = -sqrt(5) //! [Hull2D-RadiusPredicateMsqrt5] typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShapeMSqrt5.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShapeMSqrt5.png", Board2D::CairoPNG); #endif } { //alpha = -5 trace.info() << " alpha == -5 " << endl; vector<Z2i::Point> res; typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; //! [Hull2D-RadiusPredicateM5] Functor functor(false, 25, 1); //1/alpha = -sqrt(25/1) = -5 //! [Hull2D-RadiusPredicateM5] typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShapeM5.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShapeM5.png", Board2D::CairoPNG); #endif } //positive alpha shape { trace.info() << " alpha == 8 " << endl; vector<Z2i::Point> res; //! [Hull2D-RadiusPredicateP8] typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; Functor functor(true, 64, 1); //1/alpha = sqrt(64/1) = 8 typedef PredicateFromOrientationFunctor2<Functor, false, true> Predicate; Predicate predicate( functor ); //! [Hull2D-RadiusPredicateP8] closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShapeP8.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShapeP8.png", Board2D::CairoPNG); #endif } //positive alpha shape { trace.info() << " alpha == 9 " << endl; vector<Z2i::Point> res; typedef AvnaimEtAl2x2DetSignComputer<DGtal::int64_t> DetComputer; typedef InGeneralizedDiskOfGivenRadius<Z2i::Point, DetComputer> Functor; //! [Hull2D-RadiusPredicateP9] Functor functor(true, 81, 1); //1/alpha = sqrt(81/1) = 9 //! [Hull2D-RadiusPredicateP9] typedef PredicateFromOrientationFunctor2<Functor> Predicate; Predicate predicate( functor ); closedGrahamScanFromAnyPoint( border.begin(), border.end(), back_inserter( res ), predicate ); //display Board2D board; drawPolygon( res.begin(), res.end(), board ); board.saveSVG( "AlphaShapeP9.svg" ); #ifdef WITH_CAIRO board.saveCairo("AlphaShapeP9.png", Board2D::CairoPNG); #endif } }