34#include "DGtal/base/Common.h"
35#include "DGtal/kernel/SpaceND.h"
36#include "DGtal/geometry/volumes/BoundedRationalPolytope.h"
37#include "DGtalCatch.h"
48SCENARIO(
"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() ) );
176SCENARIO(
"BoundedRationalPolytope< Z3 > unit tests",
"[rational_polytope][3d]" )
183 GIVEN(
"A tetrahedron P at (0,0,0), (5/2,0,0), (0,7/2,0), (0,0,3/2)" ) {
188 Polytope P {
Point(2,2), a, b, c, d };
189 THEN(
"It contains more than 3 integer points" ) {
192 THEN(
"It contains more points than its volume" ) {
193 REQUIRE( P.count() > (5*7*3/8/6) );
195 THEN(
"It satisfies #In(P) <= #Int(P) + #Bd(P)" ) {
197 auto nb_int = P.countInterior();
198 auto nb_bd = P.countBoundary();
202 REQUIRE( nb <= nb_int + nb_bd );
204 WHEN(
"Multiplied by 4 as Q = 2 * P, it becomes a lattice polytope" ) {
206 THEN(
"Its denominator is 1" ) {
207 REQUIRE( Q.denominator() == 1 );
209 THEN(
"It has more interior and boundary points than P" ) {
211 auto nb_int = P.countInterior();
212 auto nb_bd = P.countBoundary();
213 Polytope IntQ = Q.interiorPolytope();
214 auto nb_intQ = IntQ.count();
215 auto nbQ = Q.count();
216 auto nb_bdQ = nbQ - nb_intQ;
223 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" ) {
224 Polytope Q1 = Polytope::Rational( 3 , 2 ) * P;
225 Polytope Q2 = Polytope::Rational( 2 , 1 ) * P;
226 Polytope Q3 = Polytope::Rational( 9 , 4 ) * P;
227 Polytope Q4 = Polytope::Rational( 3 , 1 ) * P;
228 Polytope Q5 = Polytope::Rational( 11, 3 ) * P;
229 auto nb = P .count();
230 auto nb1 = Q1.count();
231 auto nb2 = Q2.count();
232 auto nb3 = Q3.count();
233 auto nb4 = Q4.count();
234 auto nb5 = Q5.count();
Aim: Represents an nD rational polytope, i.e. a convex polyhedron bounded by vertices with rational c...
DGtal is the top-level namespace which contains all DGtal functions and types.
FreemanChain< int >::Vector Vector
GIVEN("A cubical complex with random 3-cells")
REQUIRE(domain.isInside(aPoint))
SCENARIO("UnorderedSetByBlock< PointVector< 2, int > unit tests with 32 bits blocks", "[unorderedsetbyblock][2d]")