34 #include "DGtal/base/Common.h"
35 #include "DGtal/kernel/SpaceND.h"
36 #include "DGtal/geometry/volumes/BoundedRationalPolytope.h"
37 #include "DGtalCatch.h"
41 using namespace DGtal;
48 SCENARIO(
"BoundedRationalPolytope< Z2 > unit tests",
"[rational_polytope][2d]" )
55 GIVEN(
"A triangle P at (0,0), (5/2,0), (0,7/2)" ) {
59 Polytope P {
Point(2,2), a, b, c };
60 THEN(
"It contains more than 3 integer points" ) {
63 THEN(
"It contains more points than its area" ) {
66 THEN(
"It satisfies #In(P) <= #Int(P) + #Bd(P)" ) {
68 auto nb_int = P.countInterior();
69 auto nb_bd = P.countBoundary();
73 REQUIRE( nb <= nb_int + nb_bd );
75 WHEN(
"Cut by some half-space" ) {
77 Q.cut(
Vector( -1, 1 ), 3 );
78 THEN(
"It contains less points" ) {
79 REQUIRE( Q.count() < P.count() );
82 WHEN(
"Multiplied by 4 as Q = 4 * P, it becomes a lattice polytope" ) {
84 THEN(
"It satisfies Pick's formula, ie 2*Area(P) = 2*#Int(P) + #Bd(P) - 2" ) {
85 Polytope IntQ = Q.interiorPolytope();
86 auto nb_int = IntQ.count();
87 auto nb_bd = Q.count() - IntQ.count();
88 auto area2 = (5*2)*(7*2);
93 REQUIRE( area2 == 2*nb_int + nb_bd - 2 );
97 GIVEN(
"A closed segment S at (4/2,0/2), (-8/2,-4/2)" ) {
100 Polytope P {
Point(2,2), a, b };
101 THEN(
"Its interior is empty #Int(P) == 0" ) {
102 auto nb_int = P.countInterior();
105 THEN(
"It satisfies #In(P) == #Int(P) + #Bd(P) == #Bd(P) == 3" ) {
107 auto nb_int = P.countInterior();
108 auto nb_bd = P.countBoundary();
112 std::vector<Point> Ppts;
117 REQUIRE( nb == nb_int + nb_bd );
120 GIVEN(
"A thin triangle P at (4/4,2/4), (2/4,4/4), (9/4,9/4)" ) {
124 Polytope P {
Point(4,4), a, b, c };
125 THEN(
"It contains 2 integer points" ) {
128 THEN(
"Its boundary is empty" ) {
129 REQUIRE( P.countBoundary() == 0 );
131 WHEN(
"Multiplied by 4 as Q = 4 * P, it becomes a lattice polytope" ) {
133 THEN(
"It satisfies Pick's formula, ie 2*Area(P) = 2*#Int(P) + #Bd(P) - 2" ) {
134 Polytope IntQ = Q.interiorPolytope();
135 auto nb_int = IntQ.count();
136 auto nb_bd = Q.count() - IntQ.count();
142 REQUIRE( area2 == 2*nb_int + nb_bd - 2 );
145 WHEN(
"Multiplied by 10/3 as Q = 10/3 * P, it is a rational polytope" ) {
146 Polytope Q = Polytope::Rational( 10, 3 ) * P;
147 THEN(
"It has a denominator 3 * gcd(4,10) == 6" ) {
148 REQUIRE( Q.denominator() == 6 );
150 THEN(
"#( 3P Cap Z2 ) <= #( Q Cap Z2 ) < #( 4P Cap Z2 )" ) {
153 auto nbQ = Q.count();
154 auto nbR = R.count();
155 auto nbS = S.count();
162 THEN(
"6/5*Q is a polytope equal to 4*P." ) {
163 Polytope R = Polytope::Rational( 6, 5 ) * Q;
165 std::vector<Point> Rpts, Spts;
170 REQUIRE( std::equal( Rpts.cbegin(), Rpts.cend(), Spts.cbegin() ) );
176 SCENARIO(
"BoundedRationalPolytope< Z3 > unit tests",
"[rational_polytope][3d]" )
182 GIVEN(
"A tetrahedron P at (0,0,0), (5/2,0,0), (0,7/2,0), (0,0,3/2)" ) {
187 Polytope P {
Point(2,2), a, b, c, d };
188 THEN(
"It contains more than 3 integer points" ) {
191 THEN(
"It contains more points than its volume" ) {
192 REQUIRE( P.count() > (5*7*3/8/6) );
194 THEN(
"It satisfies #In(P) <= #Int(P) + #Bd(P)" ) {
196 auto nb_int = P.countInterior();
197 auto nb_bd = P.countBoundary();
201 REQUIRE( nb <= nb_int + nb_bd );
203 WHEN(
"Multiplied by 4 as Q = 2 * P, it becomes a lattice polytope" ) {
205 THEN(
"Its denominator is 1" ) {
206 REQUIRE( Q.denominator() == 1 );
208 THEN(
"It has more interior and boundary points than P" ) {
210 auto nb_int = P.countInterior();
211 auto nb_bd = P.countBoundary();
212 Polytope IntQ = Q.interiorPolytope();
213 auto nb_intQ = IntQ.count();
214 auto nbQ = Q.count();
215 auto nb_bdQ = nbQ - nb_intQ;
222 WHEN(
"Considering an increasing series f_i = 3/2, 2, 9/4, 3, 11/3, the number of inside points of f_i * P is increasing" ) {
223 Polytope Q1 = Polytope::Rational( 3 , 2 ) * P;
224 Polytope Q2 = Polytope::Rational( 2 , 1 ) * P;
225 Polytope Q3 = Polytope::Rational( 9 , 4 ) * P;
226 Polytope Q4 = Polytope::Rational( 3 , 1 ) * P;
227 Polytope Q5 = Polytope::Rational( 11, 3 ) * P;
228 auto nb = P .count();
229 auto nb1 = Q1.count();
230 auto nb2 = Q2.count();
231 auto nb3 = Q3.count();
232 auto nb4 = Q4.count();
233 auto nb5 = Q5.count();
Aim: Represents an nD rational polytope, i.e. a convex polyhedron bounded by vertices with rational c...
DigitalPlane::Point Vector
DGtal is the top-level namespace which contains all DGtal functions and types.
SCENARIO("BoundedRationalPolytope< Z2 > unit tests", "[rational_polytope][2d]")
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))