DGtal 1.4.0
Loading...
Searching...
No Matches
testProjection.cpp
Go to the documentation of this file.
1
30#include <iostream>
31
32#include "DGtal/helpers/StdDefs.h"
33
34#include "DGtal/topology/SurfelAdjacency.h"
35#include "DGtal/topology/DigitalSurface.h"
36#include "DGtal/topology/helpers/BoundaryPredicate.h"
37#include "DGtal/topology/SetOfSurfels.h"
38#include "DGtal/topology/SCellsFunctors.h"
39
40#include "DGtal/shapes/Shapes.h"
41#include "DGtal/shapes/ShapeFactory.h"
42#include "DGtal/shapes/GaussDigitizer.h"
43
44#include "DGtal/io/boards/Board2D.h"
45
46#include "DGtalCatch.h"
48
49using namespace std;
50using namespace DGtal;
51using namespace Z2i;
52
54// Standard services - public :/
55
56double angle(const DGtal::Z2i::RealPoint& point)
57{
58 double angle = atan2(point[1], point[0]);
59 if(angle < 0.) angle += 2. * M_PI;
60 return angle;
61}
62
63double angle(const DGtal::Z2i::KSpace& kspace, const DGtal::Z2i::SCell& cell, const double h)
64{
66 return angle(h * emb(cell));
67}
68
69struct AngleLessCell
70{
72 typedef KSpace::SCell SCell;
73 typedef KSpace::Point Point;
74
75 AngleLessCell(const KSpace& kspace, const double h) : _kspace(kspace), _h(h)
76 {
77 }
78
79 inline bool operator()(const SCell& a, const SCell& b) const
80 {
81 return angle(_kspace, a, _h) < angle(_kspace, b, _h);
82 }
83
84 const KSpace& _kspace;
85 const double _h;
86};
87
89
90template <typename Shape>
91void digitize(Shape& shape, std::vector<SCell>& sCells0, std::vector<SCell>& sCells1, KSpace& kspace, const double h)
92{
93 // -------------------------------------------------------------------------- Type declaring
94 typedef typename DGtal::GaussDigitizer<Space, Shape> Digitizer;
95 typedef SurfelAdjacency<2> SurfelAdj;
96 typedef Surfaces<KSpace> Surf;
97
98 sCells0.clear();
99 sCells1.clear();
100
101 // -------------------------------------------------------------------------- Creating the shape
102 Digitizer digitizer;
103 digitizer.attach(shape);
104 digitizer.init(shape.getLowerBound() + Vector(-1,-1), shape.getUpperBound() + Vector(1,1), h);
105 domain = digitizer.getDomain();
106
107 kspace.init(digitizer.getLowerBound(), digitizer.getUpperBound(), true);
108
109 const SurfelAdj surfel_adjacency(true);
110 const KSpace::SCell cell_bel = Surf::findABel(kspace, digitizer);
111 Surf::track2DBoundary(sCells1, kspace, surfel_adjacency, digitizer, cell_bel);
112 {
113 typedef std::vector<Point> Points;
114 Points points;
115 Surf::track2DBoundaryPoints(points, kspace, surfel_adjacency, digitizer, cell_bel);
116 const KSpace::SCell point_ref = kspace.sCell(Point(0,0));
117 for(Points::const_iterator pi = points.begin(), pe = points.end(); pi != pe; ++pi) sCells0.push_back(kspace.sCell(*pi, point_ref));
118 }
119
120 std::sort(sCells0.begin(), sCells0.end(), AngleLessCell(kspace, h));
121 std::sort(sCells1.begin(), sCells1.end(), AngleLessCell(kspace, h));
122
123 ASSERT(sCells0.size() == sCells1.size());
124}
125
126template <typename Shape>
127bool test_shape(Shape& shape, const double h, const double epsilon)
128{
129 std::vector<SCell> sCells0, sCells1;
130
131 KSpace kspace;
132
133 digitize(shape, sCells0, sCells1, kspace, h);
134
135 CanonicSCellEmbedder<KSpace> canonicSCellEmbedder(kspace);
136
137 for(unsigned int i = 0; i < sCells0.size(); i++)
138 {
139 functors::SCellToInnerPoint<KSpace> sCellToInnerPoint(kspace);
140 functors::SCellToOuterPoint<KSpace> sCellToOuterPoint(kspace);
141
142 auto prev = ( i + sCells0.size() - 3 ) % sCells0.size(), next = (i + 3) % sCells0.size();
143
144 RealPoint inner_prev = sCellToInnerPoint( sCells0[prev] );
145 RealPoint outer_prev = sCellToOuterPoint( sCells0[prev] );
146
147 RealPoint inner_next = sCellToInnerPoint( sCells0[next] );
148 RealPoint outer_next = sCellToOuterPoint( sCells0[next] );
149
150 inner_prev *= h;
151 inner_next *= h;
152
153 outer_prev *= h;
154 outer_next *= h;
155
156 RealPoint q_prev = shape.findIntersection(inner_prev, outer_prev, epsilon);
157 RealPoint q_next = shape.findIntersection(inner_next, outer_next, epsilon);
158 RealPoint p = shape.closestPointWithWitnesses(h * canonicSCellEmbedder( sCells0[i] ), q_prev, q_next, 300);
159
160 const double norm2 = (p - h * canonicSCellEmbedder( sCells0[i]) ).norm();
161
162 if ( norm2 > sqrt(2.) * h)
163 return false;
164 }
165
166 return true;
167}
168
169TEST_CASE( "Projection test on various shapes" )
170{
171 typedef Ball2D<Space> Ball;
172 const Ball ball(Point(0,0), 1.0);
173
175 const Flower2D flower2D(Point(0,0), 1., 0.3, 5, 0.);
176
178 const AccFlower2D accFlower2D(Point(0,0), 1., 0.3, 5, 0.);
179
181 const Ellipse2D ellipse2D(Point(0,0), 1., 0.4, 0.2);
182
183 double h = 0.1;
184
185 SECTION( "Actual test" )
186 {
187 while(h > 0.01)
188 {
189 REQUIRE( test_shape( ball, h, h * 0.01 ) );
190 REQUIRE( test_shape( flower2D, h, h * 0.01 ) );
191 REQUIRE( test_shape( ellipse2D, h, h * 0.01 ) );
192 h /= 1.3;
193 }
194 }
195}
Aim: Model of the concept StarShaped represents any accelerated flower in the plane.
Definition AccFlower2D.h:65
RealPoint getLowerBound() const
Definition Astroid2D.h:122
RealPoint getUpperBound() const
Definition Astroid2D.h:131
Aim: Model of the concept StarShaped represents any circle in the plane.
Definition Ball2D.h:61
Aim: Model of the concept StarShaped represents any ellipse in the plane.
Definition Ellipse2D.h:65
Aim: Model of the concept StarShaped represents any flower with k-petals in the plane.
Definition Flower2D.h:65
Aim: A class for computing the Gauss digitization of some Euclidean shape, i.e. its intersection with...
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
bool init(const Point &lower, const Point &upper, bool isClosed)
Specifies the upper and lower bounds for the maximal cells in this space.
SCell sCell(const SPreCell &c) const
From a signed cell, returns a signed cell lying into this Khalismky space.
Aim: Implements basic operations that will be used in Point and Vector classes.
RealPoint closestPointWithWitnesses(const RealPoint &p, const RealPoint &left, const RealPoint &right, const int step) const
RealPoint findIntersection(const RealPoint &inner, const RealPoint &outer, const double epsilon) const
Aim: A utility class for constructing surfaces (i.e. set of (n-1)-cells).
Definition Surfaces.h:79
Aim: Represent adjacencies between surfel elements, telling if it follows an interior to exterior ord...
Aim: transforms a signed cell c into a point corresponding to the signed cell of greater dimension th...
Aim: transforms a signed cell c into a point corresponding to the signed cell of greater dimension th...
Space::Point Point
Definition StdDefs.h:95
DGtal is the top-level namespace which contains all DGtal functions and types.
STL namespace.
Aim: A trivial embedder for signed cell, which corresponds to the canonic injection of cell centroids...
Represents a signed cell in a cellular grid space by its Khalimsky coordinates and a boolean value.
Domain domain
void digitize(Shape &shape, std::vector< SCell > &sCells0, std::vector< SCell > &sCells1, KSpace &kspace, const double h)
bool test_shape(Shape &shape, const double h, const double epsilon)
TEST_CASE("Projection test on various shapes")
SECTION("Testing constant forward iterators")
REQUIRE(domain.isInside(aPoint))