homog2d library
Macros | Functions | Variables
homog2d_test.cpp File Reference

A test file for homog2d, needs Catch2, v2 (single header file version), see https://github.com/catchorg/Catch2
Run with $ make test More...

#include "catch.hpp"
#include "../homog2d.hpp"
#include "figures_test/polyline_inside_a1.code"
#include "figures_test/polyline_inside_a2.code"
#include "figures_test/polyline_inside_a3.code"
#include "figures_test/polyline_inside_a4.code"
#include "figures_test/polyline_inside_b1.code"
#include "figures_test/polyline_inside_b2.code"
#include "figures_test/polyline_inside_b3.code"
#include "figures_test/frect_intersect_1.code"
#include "figures_test/frect_intersect_2.code"
#include "figures_test/frect_intersect_3.code"
#include "figures_test/frect_intersect_4.code"
#include "figures_test/frect_intersect_5.code"
#include "figures_test/frect_intersect_6.code"
#include "figures_test/frect_intersect_7.code"
#include "figures_test/frect_intersect_8.code"
#include "figures_test/frect_intersect_9.code"
#include "figures_test/frect_intersect_10.code"
#include "figures_test/frect_intersect_11.code"
#include "figures_test/frect_intersect_12.code"
#include "figures_test/frect_intersect_13.code"
#include "figures_test/polyline_min_1O.code"
#include "figures_test/polyline_min_1C.code"
#include "figures_test/polyline_min_2O.code"
#include "figures_test/polyline_min_2C.code"
#include "figures_test/polyline_min_3O.code"
#include "figures_test/polyline_min_3C.code"
#include "figures_test/polyline_comp_1a.code"
#include "figures_test/polyline_comp_1b.code"
#include "figures_test/polyline_chull_1.code"
Include dependency graph for homog2d_test.cpp:

Macros

#define CATCH_CONFIG_RUNNER
 
#define HOMOG2D_BIND_X   xxx
 see test [gen_bind] More...
 
#define HOMOG2D_TEST_MODE
 
#define LOCALLOG(a)
 
#define NUMTYPE   double
 Numerical type for object storage for tests. This is usually defined by makefile. (The internal numerical type for the library is defined by HOMOG2D_INUMTYPE) More...
 
#define STR(s)   #s
 
#define XSTR(s)   STR(s)
 

Functions

 CHECK (s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
 
 CHECK (s1.getPointAt(5)==Point2d_< NUMTYPE >(5, 0))
 
 CHECK (s1.getPointAt(10)==Point2d_< NUMTYPE >(10, 0))
 
 CHECK (s1.getPointAt(20)==Point2d_< NUMTYPE >(20, 0))
 
 CHECK (pol.size()==5)
 
 CHECK (opol.size()==0)
 
 CHECK (cpol.size()==0)
 
 CHECK (cir.size()==1)
 
 CHECK (ell.size()==1)
 
 CHECK (rect.size()==4)
 
 CHECK (seg.size()==2)
 
 CHECK (li.size()==0)
 
 CHECK (pt.size()==1)
 
 CHECK (size(opol)==0)
 
 CHECK (size(cpol)==0)
 
 CHECK (size(cir)==1)
 
 CHECK (size(ell)==1)
 
 CHECK (size(rect)==4)
 
 CHECK (size(seg)==2)
 
 CHECK (size(li)==0)
 
 CHECK (size(pt)==1)
 
 CHECK_THROWS (CPolyline(-5, 5u))
 
 CHECK_THROWS (CPolyline(1, 2u))
 
 CHECK_THROWS (CPolyline(0, 5u))
 
 CHECK_THROWS (pol.set(1, 2u))
 
 CHECK_THROWS (pol.set(0, 5u))
 
 CHECK_THROWS (pol.set(-5, 5u))
 
 CHECK_THROWS (pol.set(5, 0u))
 
template<typename PT , typename CONT >
void checkSizeNF (const PT &pt, const CONT &cont)
 
long double computeDistTransformedLined (Homogr_< NUMTYPE > &H, Point2d_< NUMTYPE > pt1)
 Computation of the line passed through H^{-T} and computation of the distance between the resulting line and the transformed point. Should be 0, always. More...
 
std::string FullPrecision (long double d)
 
template<typename I >
void local_draw_test (img::Image< I > &im, std::string fn)
 Make sure all drawing functions and member functions are implemented. More...
 
 local_draw_test (im, "BUILD/dummy_draw.svg")
 
 local_draw_test (im, "BUILD/dummy_draw.png")
 
template<typename I , typename T >
void local_draw_test2 (img::Image< I > &im, T &t)
 Helper function for local_draw_test() More...
 
int main (int argc, char *argv[])
 
template<typename T , typename U >
void polytest_1 (const base::PolylineBase< T, U > &pl1)
 
pol set (8, 4u)
 
 TEST_CASE ("numerical types access", "[types-access]")
 
 TEST_CASE ("comparison testing", "[comparison-test]")
 
 TEST_CASE ("types testing 1", "[test-types-1]")
 
 TEST_CASE ("types testing 2", "[test-types-2]")
 
 TEST_CASE ("normalization", "[normaliz]")
 
 TEST_CASE ("homogeneous coordinates testing", "[homogeneous]")
 
 TEST_CASE ("infinity point", "[points-inf]")
 
 TEST_CASE ("types testing 3", "[test-types-3]")
 
 TEST_CASE ("stream operator << test", "[streamingop-test]")
 
 TEST_CASE ("line/point distance", "[lp-dist]")
 
 TEST_CASE ("side-pt-line", "[side-pt-line]")
 
 TEST_CASE ("test1", "[test1]")
 
 TEST_CASE ("build point line from container", "[build-cont]")
 
 TEST_CASE ("test throw", "[test_thr]")
 
 TEST_CASE ("test parallel", "[test_para]")
 
 TEST_CASE ("dist2points", "[t_d2p]")
 
 TEST_CASE ("Homogr constructors", "[testHC]")
 
 TEST_CASE ("test Homogr", "[testH]")
 
 TEST_CASE ("matrix inversion", "[testH3]")
 
 TEST_CASE ("line transformation", "[testH3]")
 
 TEST_CASE ("matrix chained operations", "[testH2]")
 
 TEST_CASE ("getPoints", "[test_points]")
 
 TEST_CASE ("getAngle", "[test_angle]")
 
 TEST_CASE ("getCorrectPoints", "[gcpts]")
 
 TEST_CASE ("IsInside - manual", "[IsInside_man]")
 
 TEST_CASE ("Polyline IsInside Polyline", "[tpolipol]")
 
 TEST_CASE ("Point2d IsInside Polyline", "[tptipol]")
 
 TEST_CASE ("Line2d IsInside something", "[tlir]")
 
 TEST_CASE ("Point2d IsInside Circle", "[tptic]")
 
 TEST_CASE ("Point2d IsInside FRect", "[tptir]")
 
 TEST_CASE ("Segment IsInside FRect", "[tsir]")
 
 TEST_CASE ("Circle IsInside FRect", "[tcir]")
 
 TEST_CASE ("Circle IsInside Circle", "[tcic]")
 
 TEST_CASE ("Intersection", "[int_all]")
 
 TEST_CASE ("Line/Line intersection", "[int_LL]")
 
 TEST_CASE ("Segment/Segment intersection", "[int_SS]")
 
 TEST_CASE ("Circle/Circle intersection", "[int_CC]")
 
 TEST_CASE ("FRect/FRect intersection", "[int_FF]")
 
 TEST_CASE ("IoU of 2 rectangles", "[IOU_RECT]")
 
 TEST_CASE ("Circle/Segment intersection", "[int_CS]")
 
 TEST_CASE ("Circle/FRect intersection", "[int_CF]")
 
 TEST_CASE ("Circle/Line intersection", "[int_CL]")
 
 TEST_CASE ("Line/Segment intersection", "[int_LS]")
 
 TEST_CASE ("Line/FRect intersection", "[int_LF]")
 
 TEST_CASE ("Colinearity", "[colinearity]")
 
 TEST_CASE ("Line2d", "[line1]")
 
 TEST_CASE ("Circle", "[cir1]")
 
 TEST_CASE ("Circle from points", "[cir2]")
 
 TEST_CASE ("Ellipse", "[ell1]")
 
 TEST_CASE ("OSegment point side", "[oseg-pt-side]")
 
 TEST_CASE ("Segment", "[seg1]")
 
 TEST_CASE ("Translate", "[trans]")
 
 TEST_CASE ("MoveTo", "[moveto]")
 
 TEST_CASE ("Segment-split-1", "[seg-split-1]")
 
 TEST_CASE ("Segment-split-2", "[seg-split-2]")
 
 TEST_CASE ("Segment 2", "[seg2]")
 
 TEST_CASE ("Segment extended", "[seg_extended]")
 
 TEST_CASE ("Segment orthogonal", "[seg_orthog]")
 
 TEST_CASE ("min/max of two objects", "[minmax]")
 
 TEST_CASE ("generalized bounding box of two objects", "[gen-BB]")
 
 TEST_CASE ("bounding box of container", "[BB-cont]")
 
 TEST_CASE ("common bounding box with points ", "[point2d-BB]")
 
 TEST_CASE ("FRect pair bounding box", "[frect-BB]")
 
 TEST_CASE ("bounding box of two objects", "[getBB-pair]")
 
 TEST_CASE ("FRect", "[frect]")
 
 TEST_CASE ("FRect extended", "[frect-ext]")
 
 TEST_CASE ("FRect diagonals", "[frect-diags]")
 
 TEST_CASE ("Polyline comparison 1", "[polyline-comparison-1]")
 
 TEST_CASE ("Polyline minimization", "[polyline-min]")
 
 TEST_CASE ("Polyline", "[polyline]")
 
 TEST_CASE ("Polyline setParallelogram", "[polyline-setParallelogram]")
 
 TEST_CASE ("Polyline get extreme point", "[polyline-getExtremePoint]")
 
 TEST_CASE ("Bounding Box of set of objects", "[BB-cont]")
 
 TEST_CASE ("getCenters() and getLines()", "[getCenters]")
 
 TEST_CASE ("Polygon convexity", "[polyline-convex]")
 
 TEST_CASE ("Polygon orientation", "[polyline-orient]")
 
 TEST_CASE ("Polyline basic", "[polyline-basic]")
 
 TEST_CASE ("Polyline fullstep rotation", "[polyline-rot]")
 
 TEST_CASE ("Polygon area", "[polyline-area]")
 
 TEST_CASE ("Polyline comparison 2", "[polyline-comp-2]")
 
 TEST_CASE ("convex hull", "[conv_hull]")
 
 TEST_CASE ("nearest/farthest points", "[nfp]")
 
 TEST_CASE ("pts_inside", "[ptsins]")
 
 TEST_CASE ("variant conversion tests", "[varconv]")
 
 TEST_CASE ("variant-based polymorphism", "[polymorph_1]")
 
 TEST_CASE ("SVG_Import_1", "[svg_import_1]")
 
 TEST_CASE ("SVG Import Ellipse", "[svg_import_ell]")
 
 TEST_CASE ("SVG Import path 1", "[svg_import_path_1]")
 
 TEST_CASE ("boost geometry point import", "[bg-pt-import]")
 
 TEST_CASE ("boost geometry point export", "[bg-pt-export]")
 
 TEST_CASE ("boost geometry vector point export", "[bg-vpt-export]")
 
 TEST_CASE ("Opencv build H", "[test_opencv2]")
 
 TEST_CASE ("Opencv binding", "[test_opencv]")
 

Variables

Circle cir
 
CPolyline cpol
 
Ellipse ell
 
double g_epsilon = std::numeric_limits<NUMTYPE>::epsilon()*10000.
 
Line2d li
 
CPolyline pol (5, 5u)
 
Point2d pt
 
FRect rect
 
Segment seg
 

Detailed Description

A test file for homog2d, needs Catch2, v2 (single header file version), see https://github.com/catchorg/Catch2
Run with $ make test

This file holds mostly "general" tests.

It also holds some tests that are only related to the OpenCv binding Thus, they are run only if the symbol HOMOG2D_USE_OPENCV is defined.
This latter part starts around line 3350.
Run with $ make test USE_OPENCV=Y

It also holds some tests that are only related to the SVG import feature, that requires the tinyxml2 library, and that the symbol HOMOG2D_USE_SVG_IMPORT is defined.
Run with $ make test USE_TINYXML2=Y

Macro Definition Documentation

◆ CATCH_CONFIG_RUNNER

#define CATCH_CONFIG_RUNNER

◆ HOMOG2D_BIND_X

#define HOMOG2D_BIND_X   xxx

see test [gen_bind]

◆ HOMOG2D_TEST_MODE

#define HOMOG2D_TEST_MODE

◆ LOCALLOG

#define LOCALLOG (   a)

◆ NUMTYPE

#define NUMTYPE   double

Numerical type for object storage for tests. This is usually defined by makefile. (The internal numerical type for the library is defined by HOMOG2D_INUMTYPE)

◆ STR

#define STR (   s)    #s

◆ XSTR

#define XSTR (   s)    STR(s)

Function Documentation

◆ CHECK() [1/21]

CHECK ( s1.  getPointAt0 = =Point2d_NUMTYPE >(0, 0))
Here is the caller graph for this function:

◆ CHECK() [2/21]

CHECK ( s1.  getPointAt5 = =Point2d_NUMTYPE >(5, 0))

◆ CHECK() [3/21]

CHECK ( s1.  getPointAt10 = =Point2d_NUMTYPE >(10, 0))

◆ CHECK() [4/21]

CHECK ( s1.  getPointAt20 = =Point2d_NUMTYPE >(20, 0))

◆ CHECK() [5/21]

CHECK ( pol.  size() = =5)

◆ CHECK() [6/21]

CHECK ( opol.  size() = =0)

◆ CHECK() [7/21]

CHECK ( cpol.  size() = =0)

◆ CHECK() [8/21]

CHECK ( cir.  size() = =1)

◆ CHECK() [9/21]

CHECK ( ell.  size() = =1)

◆ CHECK() [10/21]

CHECK ( rect.  size() = =4)

◆ CHECK() [11/21]

CHECK ( seg.  size() = =2)

◆ CHECK() [12/21]

CHECK ( li.  size() = =0)

◆ CHECK() [13/21]

CHECK ( pt.  size() = =1)

◆ CHECK() [14/21]

CHECK ( size(opol)  = =0)

◆ CHECK() [15/21]

CHECK ( size(cpol = =0)

◆ CHECK() [16/21]

CHECK ( size(cir = =1)

◆ CHECK() [17/21]

CHECK ( size(ell = =1)

◆ CHECK() [18/21]

CHECK ( size(rect = =4)

◆ CHECK() [19/21]

CHECK ( size(seg = =2)

◆ CHECK() [20/21]

CHECK ( size(li = =0)

◆ CHECK() [21/21]

CHECK ( size(pt = =1)

◆ CHECK_THROWS() [1/7]

CHECK_THROWS ( CPolyline(-5, 5u)  )
Here is the caller graph for this function:

◆ CHECK_THROWS() [2/7]

CHECK_THROWS ( CPolyline(1, 2u)  )

◆ CHECK_THROWS() [3/7]

CHECK_THROWS ( CPolyline(0, 5u)  )

◆ CHECK_THROWS() [4/7]

CHECK_THROWS ( pol.  set1, 2u)

◆ CHECK_THROWS() [5/7]

CHECK_THROWS ( pol.  set0, 5u)

◆ CHECK_THROWS() [6/7]

CHECK_THROWS ( pol.  set-5, 5u)

◆ CHECK_THROWS() [7/7]

CHECK_THROWS ( pol.  set5, 0u)

◆ checkSizeNF()

template<typename PT , typename CONT >
void checkSizeNF ( const PT &  pt,
const CONT &  cont 
)
3967 {
3968  CHECK_THROWS( findFarthestPoint( pt, cont ) );
3969  CHECK_THROWS( findNearestPoint( pt, cont ) );
3971 }
auto findNearestFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns indexes of points in container cont that are nearest/farthest.
Definition: homog2d.hpp:11167
size_t findFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns index of point in container cont that is the farthest to pt.
Definition: homog2d.hpp:11156
CHECK_THROWS(CPolyline(-5, 5u))
size_t findNearestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns index of point in container cont that is the nearest to pt.
Definition: homog2d.hpp:11148
Point2d pt
Definition: homog2d_test.cpp:4034
Here is the call graph for this function:
Here is the caller graph for this function:

◆ computeDistTransformedLined()

long double computeDistTransformedLined ( Homogr_< NUMTYPE > &  H,
Point2d_< NUMTYPE pt1 
)

Computation of the line passed through H^{-T} and computation of the distance between the resulting line and the transformed point. Should be 0, always.

1097 {
1098  Line2d_<NUMTYPE> line1( pt1 ); // line from (0,0) to pt1
1099  Point2d_<NUMTYPE> pt2 = H * pt1; // move the point with H
1100 // H.inverse().transpose(); // not needed, done automatically since release 2.4 !
1101  Line2d_<NUMTYPE> line2 = H * line1; // move the line with H^{-T}
1102  return line2.distTo( pt2 ); // should be 0 !
1103 }
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4223
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:
Here is the caller graph for this function:

◆ FullPrecision()

std::string FullPrecision ( long double  d)
1107 {
1108  auto s = std::ostringstream{};
1109  s << std::scientific << std::setprecision( std::numeric_limits<long double>::max_digits10 ) << d;
1110  return s.str();
1111 }
Here is the caller graph for this function:

◆ local_draw_test() [1/3]

template<typename I >
void local_draw_test ( img::Image< I > &  im,
std::string  fn 
)

Make sure all drawing functions and member functions are implemented.

No tests here, actually only checking that it builds fine

3885 {
3886  FRect r; local_draw_test2( im, r );
3887  Segment s(50,50,100,100);
3888  local_draw_test2( im, s );
3889  Circle c; local_draw_test2( im, c );
3890  Line2d li; local_draw_test2( im, li );
3891  Point2d pt; local_draw_test2( im, pt );
3892  Ellipse el; local_draw_test2( im, el );
3893  CPolyline cp; local_draw_test2( im, cp );
3894  OPolyline op; local_draw_test2( im, op );
3895 
3896  im.write( fn );
3897 }
A circle.
Definition: homog2d.hpp:378
void write(std::string) const
Definition: homog2d.hpp:752
Line2d li
Definition: homog2d_test.cpp:4035
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
void local_draw_test2(img::Image< I > &im, T &t)
Helper function for local_draw_test()
Definition: homog2d_test.cpp:3846
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ local_draw_test() [2/3]

local_draw_test ( im  ,
"BUILD/dummy_draw.svg"   
)

◆ local_draw_test() [3/3]

local_draw_test ( im  ,
"BUILD/dummy_draw.png"   
)

◆ local_draw_test2()

template<typename I , typename T >
void local_draw_test2 ( img::Image< I > &  im,
T &  t 
)

Helper function for local_draw_test()

3847 {
3848  t.draw( im );
3849  im.draw( t );
3850  draw( im, t );
3851 
3852  img::DrawParams dp;
3853  t.draw( im, dp );
3854  im.draw( t, dp );
3855  draw( im, t, dp );
3856 
3857  std::vector<T> v;
3858  t.translate( 50,20 );
3859  v.push_back(t);
3860  t.translate( 50,20 );
3861  v.push_back(t);
3862  draw( im, v );
3863  draw( im, v, dp );
3864 
3865  std::list<T> l;
3866  l.push_back(t);
3867  l.push_back(t);
3868  draw( im, l );
3869  draw( im, l, dp );
3870 
3871  std::array<T,2> a;
3872  a[0]=t;
3873  a[1]=t;
3874  draw( im, a );
3875  draw( im, a, dp );
3876 }
void draw(Data &data)
Definition: precision_test_opencv.cpp:184
Draw parameters, independent of back-end library.
Definition: homog2d.hpp:514
void draw(const U &object, img::DrawParams dp=img::DrawParams())
Definition: homog2d.hpp:891
Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)
72 {
73  std::cout << "START TESTS:"
74  << "\n - homog2d version: " << HOMOG2D_VERSION
75  << "\n - numerical type: " << XSTR(NUMTYPE)
76  << "\n - internal numerical type=" << XSTR(HOMOG2D_INUMTYPE)
77  << "\n - Catch lib version: " << CATCH_VERSION_MAJOR << '.' << CATCH_VERSION_MINOR << '.' << CATCH_VERSION_PATCH
78  << "\n - build options:"
79 
80  << "\n - HOMOG2D_OPTIMIZE_SPEED: "
81 #ifdef HOMOG2D_OPTIMIZE_SPEED
82  << "YES"
83 #else
84  << "NO"
85 #endif
86 
87  << "\n - HOMOG2D_USE_OPENCV: "
88 #ifdef HOMOG2D_USE_OPENCV
89  << "YES"
90 #else
91  << "NO"
92 #endif
93 
94  << "\n - HOMOG2D_USE_SVG_IMPORT: "
95 #ifdef HOMOG2D_USE_SVG_IMPORT
96  << "YES"
97 #else
98  << "NO"
99 #endif
100 
101  << "\n - HOMOG2D_ENABLE_PRTP: "
102 #ifdef HOMOG2D_ENABLE_PRTP
103  << "YES"
104 #else
105  << "NO"
106 #endif
107 
108  << "\n - HOMOG2D_ENABLE_VRTP: "
109 #ifdef HOMOG2D_ENABLE_VRTP
110  << "YES"
111 #else
112  << "NO"
113 #endif
114  << '\n';
115 
116  Catch::StringMaker<float>::precision = 25;
117  Catch::StringMaker<double>::precision = 25;
118 
119 // removed until PR merged into next release, see https://github.com/catchorg/Catch2/pull/2245
120 // Catch::StringMaker<long double>::precision = 25;
121 
122 // we need to have a bigger threshold value for "float" type, as it has a lot less precision
123  if( std::string( XSTR(NUMTYPE) ) == "float" )
124  thr::nullDistance() = 1E-6;
125 
126  thr::printThresholds( std::cout );
127 
128  return Catch::Session().run( argc, argv );
129 }
#define HOMOG2D_VERSION
Definition: homog2d.hpp:231
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1195
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
#define NUMTYPE
Numerical type for object storage for tests. This is usually defined by makefile. (The internal numer...
Definition: homog2d_test.cpp:49
#define XSTR(s)
Definition: homog2d_test.cpp:68
void printThresholds(std::ostream &f)
Helper function, could be needed.
Definition: homog2d.hpp:1232
Here is the call graph for this function:

◆ polytest_1()

template<typename T , typename U >
void polytest_1 ( const base::PolylineBase< T, U > &  pl1)
3247 {
3248  CHECK( pl1.isSimple() == false );
3249  CHECK( isSimple(pl1) == false );
3250 
3251  CHECK( pl1.size() == 0 );
3252  CHECK( size(pl1) == 0 );
3253 
3254  CHECK( pl1.nbSegs() == 0 );
3255  CHECK( nbSegs(pl1) == 0 );
3256 
3257  CHECK( pl1.length() == 0 );
3258  CHECK( length(pl1) == 0 );
3259 
3260  CHECK( pl1.area() == 0 );
3261  CHECK( area(pl1) == 0 );
3262 
3263  CHECK_THROWS( centroid(pl1) ); // unable
3264  CHECK_THROWS( pl1.centroid() ); // unable
3265 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6245
HOMOG2D_INUMTYPE length() const
Returns length of Polyline.
Definition: homog2d.hpp:7465
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7381
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
HOMOG2D_INUMTYPE length(const T &elem)
Returns length of element or variant (free function)
Definition: homog2d.hpp:10223
base::LPBase< typ::IsPoint, FPT > centroid(const base::PolylineBase< PLT, FPT > &pl)
Returns centroid of Polyline (free function)
Definition: homog2d.hpp:10907
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10253
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10238
size_t nbSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the number of segments (free function)
Definition: homog2d.hpp:9927
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6211
LPBase< typ::IsPoint, HOMOG2D_INUMTYPE > centroid() const
Compute centroid of polygon.
Definition: homog2d.hpp:7518
HOMOG2D_INUMTYPE area() const
Returns area of polygon (computed only if necessary)
Definition: homog2d.hpp:7481
bool isSimple(const base::PolylineBase< PLT, FPT > &pl)
Returns true if is a polygon (free function)  
Definition: homog2d.hpp:9907
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set()

pol set ( ,
4u   
)

◆ TEST_CASE() [1/93]

TEST_CASE ( "numerical types access"  ,
""  [types-access] 
)
132 {
133  Point2dF ptF;
134  Point2dD ptD;
135  Point2dL ptL;
136 
137  Line2dF liF;
138  Line2dD liD;
139  Line2dL liL;
140 
141  HomogrF HF;
142  HomogrD HD;
143  HomogrL HL;
144 
145  FRectF rF;
146  FRectD rD;
147  FRectL rL;
148 
149  SegmentF sF;
150  SegmentD sD;
151  SegmentL sL;
152 
153  CircleF cF;
154  CircleD cD;
155  CircleL cL;
156 
157  OPolylineF poF;
158  OPolylineD poD;
159  OPolylineL poL;
160 
161  CPolylineF pcF;
162  CPolylineD pcD;
163  CPolylineL pcL;
164 
165  EllipseF eF;
166  EllipseD eD;
167  EllipseL eL;
168 
169  CHECK( ptF.dtype() == dtype(ptF) );
170 
171  CHECK( ptF.dtype() == Dtype::Float );
172  CHECK( liF.dtype() == Dtype::Float );
173  CHECK( HF.dtype() == Dtype::Float );
174  CHECK( rF.dtype() == Dtype::Float );
175  CHECK( sF.dtype() == Dtype::Float );
176  CHECK( cF.dtype() == Dtype::Float );
177  CHECK( poF.dtype() == Dtype::Float );
178  CHECK( pcF.dtype() == Dtype::Float );
179  CHECK( eF.dtype() == Dtype::Float );
180 
181  CHECK( ptD.dtype() == Dtype::Double );
182  CHECK( liD.dtype() == Dtype::Double );
183  CHECK( HD.dtype() == Dtype::Double );
184  CHECK( rD.dtype() == Dtype::Double );
185  CHECK( sD.dtype() == Dtype::Double );
186  CHECK( cD.dtype() == Dtype::Double );
187  CHECK( poD.dtype() == Dtype::Double );
188  CHECK( pcD.dtype() == Dtype::Double );
189  CHECK( eD.dtype() == Dtype::Double );
190 
191  CHECK( dtype(ptD) == Dtype::Double );
192  CHECK( dtype(liD) == Dtype::Double );
193  CHECK( dtype(HF) == Dtype::Float );
194  CHECK( dtype(rF) == Dtype::Float );
195 
196  CHECK( dsize(ptF).first == ptF.dsize().first );
197  CHECK( dsize(ptD).first == ptD.dsize().first );
198  CHECK( dsize(ptL).first == ptL.dsize().first );
199 
200  CHECK( dsize(ptF).second == ptF.dsize().second );
201  CHECK( dsize(ptD).second == ptD.dsize().second );
202  CHECK( dsize(ptL).second == ptL.dsize().second );
203 
204  CHECK( dsize(ptF).first == 24 );
205  CHECK( dsize(ptF).second == 7 );
206 
207  CHECK( dsize(ptD).first == 53 );
208  CHECK( dsize(ptD).second == 10 );
209 
210  CHECK( dsize(ptL).first == 64 );
211  CHECK( dsize(ptL).second == 63 );
212 }
A circle.
Definition: homog2d.hpp:378
std::pair< int, int > dsize() const
Get data size expressed as number of bits for, respectively, mantissa and exponent.
Definition: homog2d.hpp:1345
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Dtype dtype(const T &elem)
Returns the underlying data type of object or variant.
Definition: homog2d.hpp:10208
Dtype dtype() const
Get numerical data type as a Dtype value, can be stringified with h2d::getString(Dtype) ...
Definition: homog2d.hpp:1338
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
std::pair< int, int > dsize(const T &t)
Get data size expressed as number of bits for, respectively, mantissa and exponent.
Definition: homog2d.hpp:10952
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:
Here is the caller graph for this function:

◆ TEST_CASE() [2/93]

TEST_CASE ( "comparison testing"  ,
""  [comparison-test] 
)
215 {
216  {
218  a1, a2; CHECK( a1 == a2 );
219  }
220  {
222  a1, a2; CHECK( a1 == a2 );
223  }
224  {
226  a1, a2; CHECK( a1 == a2 );
227  }
228  {
230  a1, a2; CHECK( a1 == a2 );
231  }
232  {
234  a1, a2; CHECK( a1 == a2 );
235  }
236  {
238  a1, a2; CHECK( a1 == a2 );
239  }
240  {
242  a1, a2; CHECK( a1 == a2 );
243  }
244  {
246  a1, a2; CHECK( a1 == a2 );
247  }
248 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [3/93]

TEST_CASE ( "types testing 1"  ,
""  [test-types-1] 
)
252 {
253  INFO( "type size" )
254  {
255  Point2dF ptF;
256  Point2dD ptD;
257  Point2dL ptL;
258 
259  Line2dF liF;
260  Line2dD liD;
261  Line2dL liL;
262 
263  HomogrF HF;
264  HomogrD HD;
265  HomogrL HL;
266 
267  Point2d pt(4.,5); // checking with 2 different types
268  Point2d_<float> pt2F1;
269  Point2d_<double> pt2F2;
270  Point2d_<long double> pt2F3;
271  pt2F1.set(4.,5); // checking with 2 different types
272 
273  CHECK( ptF.type() == Type::Point2d );
274  CHECK( liF.type() == Type::Line2d );
275  }
276 
277  Point2dD ptD0(1,1);
278  Point2dF ptF0(2,2);
279  Point2dL ptL0(3,3);
280 
281  Line2dD li_D0(1,1);
282  Line2dF li_F0(2,2);
283  Line2dL li_L0(3,3);
284 }
Type type() const
Definition: homog2d.hpp:4049
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12376
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [4/93]

TEST_CASE ( "types testing 2"  ,
""  [test-types-2] 
)
287 {
288  Point2dD ptD0(1,1);
289  Point2dF ptF0(2,2);
290  Point2dL ptL0(3,3);
291 
292  INFO( "numerical type conversions (assignment)" )
293  {
294  Point2dD ptD(4,4);
295  Point2dF ptF(5,5);
296  Point2dL ptL(6,6);
297 
298  ptL = ptD0;
299  CHECK( ptL.getX() == 1. );
300  ptL = ptF0;
301  CHECK( ptL.getX() == 2. );
302 
303  ptF = ptD0;
304  CHECK( ptF.getX() == 1. );
305  ptF = ptL0;
306  CHECK( ptF.getX() == 3. );
307 
308  ptD = ptF0;
309  CHECK( ptD.getX() == 2. );
310  ptD = ptL0;
311  CHECK( ptD.getX() == 3. );
312 
313  CircleF cf;
314  CircleD cd;
315  CircleL cl;
316  cl = cd;
317  cf = cd;
318  cd = cf;
319  cl = cf;
320  cf = cl;
321  cd = cl;
322 
323  SegmentF sf;
324  SegmentD sd;
325  SegmentL sl;
326  sl = sd;
327  sf = sd;
328  sd = sf;
329  sl = sf;
330  sf = sl;
331  sd = sl;
332 
333  FRectF rf;
334  FRectD rd;
335  FRectL rl;
336  rl = rd;
337  rf = rd;
338  rd = rf;
339  rl = rf;
340  rf = rl;
341  rd = rl;
342 
343  OPolylineF pof;
344  OPolylineD pod;
345  OPolylineL pol;
346 
347  pol = pod;
348  pof = pod;
349  pod = pof;
350  pol = pof;
351  pof = pol;
352  pod = pol;
353  }
354 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline pol(5, 5u)
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [5/93]

TEST_CASE ( "normalization"  ,
""  [normaliz] 
)
357 {
358  Point2d_<NUMTYPE> pt1(1,2,3);
359  CHECK( pt1.get() == std::array<NUMTYPE,3>{1,2,3} );
360  Point2d_<NUMTYPE> pt2(-1,2,3);
361  CHECK( pt2.get() == std::array<NUMTYPE,3>{1,-2,-3} );
362 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [6/93]

TEST_CASE ( "homogeneous coordinates testing"  ,
""  [homogeneous] 
)
365 {
366  {
367  Point2d_<NUMTYPE> pt1(2,2,1);
368  Point2d_<NUMTYPE> pt2(4,4,2);
369  CHECK( pt1 == pt2 );
370  pt2.set(8,8,4);
371  CHECK( pt1 == pt2 );
372 
373  Line2d_<NUMTYPE> li1(0,1,0);
374  Line2d_<NUMTYPE> li2(0,2,0);
375  CHECK( li1 == li2 );
376  li2.set(0,4,0);
377  CHECK( li1 == li2 );
378 
379  Line2d_<NUMTYPE> li3(3,4,5);
380  Line2d_<NUMTYPE> li4(6,8,10);
381  CHECK( li3 == li4 );
382  }
383  {
384  INFO( "constructors using a container of values as single argument" );
385 
386  std::array<float,3> arr{3,2,1};
387  Point2d_<NUMTYPE> pt1(arr);
388  CHECK( pt1 == Point2d_<NUMTYPE>(3,2,1) );
389 
390  std::vector<float> vec{3,2,1};
391  Point2d_<NUMTYPE> pt2(vec);
392  CHECK( pt2 == Point2d_<NUMTYPE>(3,2,1) );
393  }
394 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [7/93]

TEST_CASE ( "infinity point"  ,
""  [points-inf] 
)
397 {
398  Line2d liH( LineDir::H, Point2d() ); // horizontal line at y=0
399  CHECK_THROWS( Point2d(0,0,0) );
400  CHECK_THROWS( Line2d(0,0,0) );
401 
402  Point2d pt1(1,0,0);
403  Point2d pt2(-1,0,0);
404  CHECK( pt1.isInf() );
405  CHECK( pt2.isInf() );
406 
407  auto li1 = pt1 * Point2d();
408  CHECK( li1 == liH );
409  auto li2 = pt2 * Point2d();
410  CHECK( li2 == liH );
411 
412  Point2d pt3(3,3,0); // infinite points at an angle of 45°
413  auto li3 = pt3 * Point2d();
414  CHECK( std::abs(li3.getAngle( liH ) - M_PI/4.) < g_epsilon );
415 
416  Segment seg( Point2d(), pt1 );
417  auto ppts = seg.getPts();
418 
419  auto line = seg.getLine();
420  CHECK( line == liH );
421 }
Segment seg
Definition: homog2d_test.cpp:4033
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12376
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
double g_epsilon
Definition: homog2d_test.cpp:64
PointPair_< FPT > getPts() const
Returns the points of segment as a std::pair.
Definition: homog2d.hpp:5197
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
auto getLine() const
Returns supporting line.
Definition: homog2d.hpp:5252
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [8/93]

TEST_CASE ( "types testing 3"  ,
""  [test-types-3] 
)

The goal of these is to make sure that the conversion (float to double, ...) does not trigger a build failure. The checking is only there to avoid a warning about "unused variable".

Todo:
Once we switch to C++17, we can remove the checking and use: https://en.cppreference.com/w/cpp/language/attributes/maybe_unused
424 {
425  Point2dD ptD0(1,1); // double
426  Point2dF ptF0(2,2); // float
427  Point2dL ptL0(3,3); // long
428 
429  INFO( "numerical type conversions (copy-constructor)" )
430  {
431  Point2dL ptL1 = ptD0; // double to long
432  Point2dL ptL2 = ptF0; // float to long
433  CHECK( ptL1.getX() == 1. );
434  CHECK( ptL2.getX() == 2. );
435 
436  Point2dF ptF1 = ptD0;
437  Point2dF ptF2 = ptL0;
438  CHECK( ptF1.getX() == 1. );
439  CHECK( ptF2.getX() == 3. );
440 
441  Point2dD ptD1 = ptF0;
442  Point2dD ptD2 = ptL0;
443  CHECK( ptD1.getX() == 2. );
444  CHECK( ptD2.getX() == 3. );
445 
446  CircleL cl;
447  CircleF cf;
448  CircleD cd;
449 
450  CircleL cl2 = cd;
451  CircleF cf2 = cd;
452  CircleD cd2 = cd;
453 
454  CircleL cl3 = cf;
455  CircleF cf3 = cf;
456  CircleD cd3 = cf;
457 
458  CircleL cl4 = cl;
459  CircleF cf4 = cl;
460  CircleD cd4 = cl;
461 
462  SegmentL sl;
463  SegmentF sf;
464  SegmentD sd;
465 
466  SegmentL sl2 = sd;
467  SegmentF sf2 = sd;
468  SegmentD sd2 = sd;
469 
470  SegmentL sl3 = sf;
471  SegmentF sf3 = sf;
472  SegmentD sd3 = sf;
473 
474  SegmentL sl4 = sl;
475  SegmentF sf4 = sl;
476  SegmentD sd4 = sl;
477 
478  FRectL rl;
479  FRectF rf;
480  FRectD rd;
481 
482  FRectL rl2 = rd;
483  FRectF rf2 = rd;
484  FRectD rd2 = rd;
485 
486  FRectL rl3 = rf;
487  FRectF rf3 = rf;
488  FRectD rd3 = rf;
489 
490  FRectL rl4 = rl;
491  FRectF rf4 = rl;
492  FRectD rd4 = rl;
493 
494  OPolylineL pol;
495  OPolylineF pof;
496  OPolylineD pod;
497 
498  OPolylineL pol2 = pod;
499  OPolylineF pof2 = pod;
500  OPolylineD pod2 = pod;
501 
502  OPolylineL pol3 = pof;
503  OPolylineF pof3 = pof;
504  OPolylineD pod3 = pof;
505 
506  OPolylineL pol4 = pol;
507  OPolylineF pof4 = pol;
508  OPolylineD pod4 = pol;
509 
510  CPolylineL pcl;
511  CPolylineF pcf;
512  CPolylineD pcd;
513 
514  CPolylineL pcl2 = pcd;
515  CPolylineF pcf2 = pcd;
516  CPolylineD pcd2 = pcd;
517 
518  CPolylineL pcl3 = pcf;
519  CPolylineF pcf3 = pcf;
520  CPolylineD pcd3 = pcf;
521 
522  CPolylineL pcl4 = pcl;
523  CPolylineF pcf4 = pcl;
524  CPolylineD pcd4 = pcl;
525 
526  EllipseL elll;
527  EllipseF ellf;
528  EllipseD elld;
529 
530  EllipseL elll2 = elld;
531  EllipseF ellf2 = elld;
532  EllipseD elld2 = elld;
533 
534  EllipseL elll3 = ellf;
535  EllipseF ellf3 = ellf;
536  EllipseD elld3 = ellf;
537 
538  EllipseL elll4 = elll;
539  EllipseF ellf4 = elll;
540  EllipseD elld4 = elll;
541 
549  Line2dD li_D0(1,1);
550  Line2dF li_F0(2,2);
551  Line2dL li_L0(3,3);
552 
553  Line2dD li_D1 = li_F0; CHECK( li_D1.get()[2] == 0. );
554  Line2dD li_L1 = li_F0; CHECK( li_L1.get()[2] == 0. );
555 
556  Line2dD li_F2 = li_D0; CHECK( li_F2.get()[2] == 0. );
557  Line2dD li_L2 = li_D0; CHECK( li_L2.get()[2] == 0. );
558 
559  Line2dD li_F3 = li_L0; CHECK( li_F3.get()[2] == 0. );
560  Line2dD li_D3 = li_L0; CHECK( li_D3.get()[2] == 0. );
561  }
562 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline pol(5, 5u)
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
HOMOG2D_INUMTYPE getX() const
Definition: homog2d.hpp:4129
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
std::array< FPT, 3 > get() const
Definition: homog2d.hpp:4203
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [9/93]

TEST_CASE ( "stream operator << test"  ,
""  [streamingop-test] 
)
565 {
566  Line2d li;
567  Point2d pt;
568  Segment seg;
569  OSegment vec;
570  Circle cir;
571  Ellipse ell;
572  CPolyline cpol;
573  OPolyline opol;
574 // just to make sure that this builds !
575  std::ostringstream oss;
576  oss << li << pt << seg << vec << cir << cpol << opol << ell;
577  std::ostringstream oss2;
578  oss2 << cpol;
579  CHECK( oss2.str() == "CPolyline: empty" );
580 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Ellipse ell
Definition: homog2d_test.cpp:4037
CPolyline cpol
Definition: homog2d_test.cpp:4030
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4034
Circle cir
Definition: homog2d_test.cpp:4036
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [10/93]

TEST_CASE ( "line/point distance"  ,
""  [lp-dist] 
)
583 {
584  size_t n = 1E6; // nb of runs
585  size_t c1{};
586  size_t c2{};
587  long double sum1{};
588  long double sum2{};
589  float k = 1;
590  std::srand( time(0) );
591  for( size_t i=0; i<n; i++ )
592  {
593  Point2d_<NUMTYPE> pt1(
594  1.0*rand()/RAND_MAX * k,
595  1.0*rand()/RAND_MAX * k
596  );
597  Point2d_<NUMTYPE> pt2(
598  1.0*rand()/RAND_MAX * k,
599  1.0*rand()/RAND_MAX * k
600  );
601  auto li = pt1 * pt2;
602  auto d1 = li.distTo(pt1);
603  auto d2 = li.distTo(pt2);
604  if( d1 > thr::nullDistance() )
605  {
606 // std::cerr << ": distance check failure 1, value " << d1 << " > thres (" << thr::nullDistance() << ")\n";
607  sum1 += d1;
608  c1++;
609  }
610  if( li.distTo(pt2) > thr::nullDistance() )
611  {
612 // std::cerr << "distance check failure 2, value " << d2 << " > thres (" << thr::nullDistance() << ")\n";
613  sum2 += d2;
614  c2++;
615  }
616  }
617  if( c1 != 0 || c2 != 0 )
618  {
619  std::cout << "line/point distance test failures with thres=" << thr::nullDistance()
620  << "\n nb1=" << c1 << ", nb2=" << c2 << " failures over total nb of tests=" << n
621  << "\n- mean distance: d1=" << sum1 / c1
622  << "\n- mean distance: d2=" << sum2 / c2
623  << '\n';
624  }
625  CHECK( c1 == 0 );
626  CHECK( c2 == 0 );
627 }
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1195
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4223
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [11/93]

TEST_CASE ( "side-pt-line"  ,
""  [side-pt-line] 
)
630 {
631  Line2d_<NUMTYPE> li; // vertical line at x=0
632  {
634  CHECK( side(pt,li) == 0 );
635  }
636  {
637  Point2d_<NUMTYPE> pt(1,0);
638  CHECK( side(pt,li) == 1 );
639  }
640  {
641  Point2d_<NUMTYPE> pt(-1,0);
642  CHECK( side(pt,li) == -1 );
643  }
644 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
int side(const Point2d_< FPT1 > &pt, const Line2d_< FPT2 > &li)
Free function, returns -1 or +1 depending on the side of pt, related to li.
Definition: homog2d.hpp:9829
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [12/93]

TEST_CASE ( "test1"  ,
""  [test1] 
)
647 {
648  Point2d_<NUMTYPE> ptA1; // 0,0
649  CHECK( ptA1 == Point2d_<NUMTYPE>(0,0) );
650 
651  Point2d_<NUMTYPE> ptA2(2,2);
652  CHECK( ptA2.getX() == 2. );
653  CHECK( ptA2.getY() == 2. );
654 
655  { // build line from one point, other one will be (0,0)
656  Line2d_<NUMTYPE> lA1( ptA2 );
657  CHECK( lA1.distTo( ptA1 ) == 0 );
658  CHECK( lA1.distTo( ptA2 ) == 0 );
659 
660  CHECK( ptA1.distTo( lA1 ) == 0 );
661  CHECK( ptA2.distTo( lA1 ) == 0 );
662  }
663 
664  { // build line from two points
665  Line2d_<NUMTYPE> lA1 = ptA1 * ptA2;
666  Line2d_<NUMTYPE> lA2 = ptA2 * ptA1;
667 
668  CHECK( lA1 == lA2 );
669  CHECK( lA1.getAngle(lA2) == 0. );
670  CHECK( lA2.getAngle(lA1) == 0. );
671  CHECK( getAngle(lA1,lA2) == 0. );
672 
673  Point2d_<NUMTYPE> ptB1(0,2);
674  Point2d_<NUMTYPE> ptB2(2,0);
675  Line2d_<NUMTYPE> lB = ptB1 * ptB2;
676 
677  auto v1 = lB.getCoord( GivenCoord::X, 1 );
678  CHECK( v1 == 1. );
679  CHECK( lB.getPoint( GivenCoord::X, 1) == Point2d_<NUMTYPE>(1,1) );
680  }
681  {
682 // build point from two diagonal lines
683  Line2d_<NUMTYPE> liA( Point2d(0,0), Point2d(2,2) );
684  Line2d_<NUMTYPE> liB( Point2d(0,2), Point2d(2,0) );
685  CHECK( Line2d_<NUMTYPE>() != liA );
686 
687  auto mA1 = liA * liB;
688  auto mA2 = liB * liA;
689  CHECK( mA1 == Point2d_<NUMTYPE>(1.,1.) );
690  CHECK( mA2 == Point2d_<NUMTYPE>(1.,1.) );
691  CHECK( mA1 != Point2d_<NUMTYPE>() );
692 
693 // build point from two H/V lines
694  Line2d_<NUMTYPE> lv0( 0, 1 ); // vertical, x=0
695  Line2d_<NUMTYPE> lh0( 1, 0 ); // horizontal, x=0
696 
697  CHECK( lv0 * lh0 == Point2d_<NUMTYPE>(0.,0.) );
698  CHECK( lh0 * lv0 == Point2d_<NUMTYPE>(0.,0.) );
699 
700  Line2d_<NUMTYPE> lv2( Point2d(2,0), Point2d(2,2) ); // vertical, x=2
701  Line2d_<NUMTYPE> lh2( Point2d(0,2), Point2d(2,2) ); // horizontal, y=2
702 
703  CHECK( lv2*lh2 == Point2d_<NUMTYPE>(2.,2.) );
704 
705  CHECK( lv0*liA == Point2d_<NUMTYPE>() );
706  CHECK( lh0*liA == Point2d_<NUMTYPE>() );
707 
708  CHECK( lv0*liB == Point2d_<NUMTYPE>(0,2) );
709  CHECK( lh0*liB == Point2d_<NUMTYPE>(2,0) );
710 
711  CHECK( lv2*liA == Point2d_<NUMTYPE>(2.,2.) );
712  CHECK( lh2*liA == Point2d_<NUMTYPE>(2.,2.) );
713 
714  CHECK( lv2*liB == Point2d_<NUMTYPE>(2.,0.) );
715  CHECK( lh2*liB == Point2d_<NUMTYPE>(0.,2.) );
716  }
717 
718  { // test of getOrthogonal()
719  Line2d_<NUMTYPE> lV; // vertical line at x=0
720 
721 // get orthogonal line at y=100
722  Line2d_<NUMTYPE> li2 = lV.getOrthogLine( GivenCoord::Y, 100 );
723  CHECK( li2.getAngle( lV ) == Approx(M_PI/2.) );
724  CHECK( getAngle( li2,lV ) == Approx(M_PI/2.) );
725 
726  Line2d_<NUMTYPE> lH2(1,0); // build horizontal line
727  Line2d_<NUMTYPE> lH3 = lH2;
728  CHECK( lH2.getAngle(lH3) == 0. );
729  }
730  {
731  Line2d_<NUMTYPE> li(4,2);
732  CHECK( li.getCoord( GivenCoord::X, 2 ) == 1 );
733  CHECK( li.getCoord( GivenCoord::Y, 1 ) == 2 );
734  CHECK( li.getPoint( GivenCoord::X, 2 ) == Point2d_<NUMTYPE>(2,1) );
735  CHECK( li.getPoint( GivenCoord::Y, 1 ) == Point2d_<NUMTYPE>(2,1) );
736  }
737  {
738  Line2d_<NUMTYPE> liv1( LineDir::V, 10. );
739  Line2d_<NUMTYPE> liv2( Point2d(10,0), Point2d(10,20) );
740  CHECK( liv1 == liv2 );
741  Line2d_<NUMTYPE> lih1( LineDir::H, 10. );
742  Line2d_<NUMTYPE> lih2( Point2d(0,10), Point2d(20,10) );
743  CHECK( lih1 == lih2 );
744  }
745 }
Line2d_< FPT > getOrthogLine(GivenCoord gc, FPT2 other) const
Returns an orthogonal line to the one it is called on, at a point on the line defined by one of its c...
Definition: homog2d.hpp:8878
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9204
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
Point2d_< FPT > getPoint(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:4071
HOMOG2D_INUMTYPE getAngle(const LPBase< T, FPT2 > &other) const
Line2d li
Definition: homog2d_test.cpp:4035
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8831
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4223
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [13/93]

TEST_CASE ( "build point line from container"  ,
""  [build-cont] 
)
748 {
749  std::array<double,3> arr{3,2,1};
750  Point2d_<NUMTYPE> pt( arr );
751  CHECK( pt == Point2d(3,2,1) );
752 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [14/93]

TEST_CASE ( "test throw"  ,
""  [test_thr] 
)
755 {
756  Line2d li;
757  CHECK_THROWS( li.getCoord( GivenCoord::X, 0 ) );
758 
759  INFO("Lines and points");
760  {
761  Line2d_<NUMTYPE> v1,v2; // 2 identical vertical lines
762  CHECK_THROWS( v1*v2 );
763 
764  Point2d_<NUMTYPE> p1,p2;
765  CHECK_THROWS( p1*p2 ); // same points can't define a line
766  }
767  INFO("rectangle constructor")
768  {
769  Point2d_<NUMTYPE> p1, p2;
770  CHECK_THROWS( FRect( p1,p2) );
771  p2.set( 1, 1);
772  CHECK_NOTHROW( FRect( p1,p2) );
773  CHECK( FRect_<NUMTYPE>( p1,p2).getPts()==std::make_pair(Point2d_<NUMTYPE>(0,0),Point2d_<NUMTYPE>(1,1) ) );
774  p1.set( 4, 4 );
775  p2.set( 5, 5 );
776  CHECK_NOTHROW( FRect( p1,p2) );
777  p1.set( 4, 5 );
778  p2.set( 5, 4 );
779  CHECK_NOTHROW( FRect( p1,p2) );
780  p1.set( 5, 4 );
781  p2.set( 4, 5 );
782  CHECK_NOTHROW( FRect( p1,p2) );
783 
784  p1.set( 4, 4 );
785  p2.set( 5, 4 );
786  CHECK_THROWS( FRect( p1,p2) );
787  p2.set( 4, 5 );
788  CHECK_THROWS( FRect( p1,p2) );
789  }
790  INFO("circle constructor") // 0 not allowed as radius
791  {
793  CHECK_THROWS( Circle_<NUMTYPE> ( pt, 0 ) );
795  CHECK_NOTHROW( Circle_<NUMTYPE> ( pt, thr::nullDistance()*1.1 ) );
796  }
797  INFO("segment constructor") // can't have identical points
798  {
801  }
802 }
A circle.
Definition: homog2d.hpp:378
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1195
std::vector< RT > getPts(const std::vector< Point2d_< FPT >> &vpt)
Free function, returns a vector of points of other type from a vector of h2d points.
Definition: homog2d.hpp:4661
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8831
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [15/93]

TEST_CASE ( "test parallel"  ,
""  [test_para] 
)
805 {
806  INFO( "Checking angle" )
807  {
808  Line2d_<NUMTYPE> l1; // vertical line
809  Line2d_<NUMTYPE> l2a( Point2d_<NUMTYPE>(0,0),Point2d_<NUMTYPE>(1,1) ); // 45° line, starting at (0,0)
810  CHECK( getAngle( l1, l2a ) == Approx( M_PI/4. ) );
811 
812  Line2d_<NUMTYPE> l2b( Point2d_<NUMTYPE>(3,0),Point2d_<NUMTYPE>(4,1) ); // 45° line, starting at (3,0)
813  CHECK( getAngle( l1, l2b ) == Approx( M_PI/4. ) );
814 
815 // l2b.addOffset( LineOffset::horiz, 10. );
816 // CHECK( getAngle( l1, l2b ) == Approx( M_PI/4. ) );
817 // l2b.addOffset( LineOffset::vert, 10. );
818 // CHECK( getAngle( l1, l2b ) == Approx( M_PI/4. ) );
819  }
820 
821  INFO( "Checking parallel lines" )
822  {
823  Line2d_<NUMTYPE> l1, l1b; // vertical line
824  CHECK( l1.isParallelTo(l1b) );
825  {
826  Line2d_<NUMTYPE> l2a(Point2d_<NUMTYPE>(1.,0.), Point2d_<NUMTYPE>(1.0005,1.) ); // almost vertical line
827  CHECK( l1.isParallelTo(l2a) == true );
828 
829  Line2d_<NUMTYPE> l2b(Point2d_<NUMTYPE>(1.,0.), Point2d_<NUMTYPE>(1.002,1.) ); // almost vertical line
830  CHECK( l1.isParallelTo(l2b) == false );
831  }
832  thr::nullAngleValue() = 0.01;
833  {
834  Line2d_<NUMTYPE> l2a(Point2d_<NUMTYPE>(1.,0.), Point2d_<NUMTYPE>(1.0005,1.) ); // almost vertical line
835  INFO( "angle=" << getAngle( l1,l2a) );
836  CHECK( l1.isParallelTo(l2a) == true );
837 
838  Line2d_<NUMTYPE> l2b(Point2d_<NUMTYPE>(1.,0.), Point2d_<NUMTYPE>(1.02,1.) ); // almost vertical line
839  INFO( "angle=" << getAngle( l1,l2b) );
840  CHECK( l1.isParallelTo(l2b) == false );
841  }
842  //l1.isParallelTo( Point2d() ); // NO BUILD
843  }
844  INFO( "Vertical line at x=0" )
845  {
846  Line2d_<NUMTYPE> l1; // vertical line
847 
849  CHECK_THROWS( l1 * l2 ); // two parallel lines never cross
850  CHECK( l2.distTo( Point2d_<NUMTYPE>(0,0) ) == 1. );
851  CHECK( l2.distTo( Point2d_<NUMTYPE>(0,2) ) == 1. );
852  CHECK( getAngle(l2,l1) == 0. );
853 
855  CHECK( l3.distTo( Point2d_<NUMTYPE>(0,0) ) == 0. );
856  CHECK( l3.distTo( Point2d_<NUMTYPE>(0,2) ) == 0. );
857  CHECK( getAngle(l3,l1) == 0. );
858  }
859  INFO( "dist parallel lines" )
860  {
861  Line2d_<NUMTYPE> l1; // vertical line at x=0
862  Line2d_<NUMTYPE> l2( Point2d(1,0), Point2d(1,10) ); // vertical line at x=1
863  CHECK( getParallelDistance( l1, l2 ) == 1. );
864  Line2d_<NUMTYPE> l3( Point2d(-3,0), Point2d(-3,-10) ); // vertical line at x=1
865  CHECK( getParallelDistance( l1, l3 ) == 3. );
866  CHECK( getParallelDistance( l2, l3 ) == 4. );
867 
868  Line2d_<NUMTYPE> l4( LineDir::H, 1 ); // horizontal line
869  CHECK_THROWS( getParallelDistance( l1, l4 ) );
870  }
871 }
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9204
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
HOMOG2D_INUMTYPE getParallelDistance(const Line2d_< FPT > &li1, const Line2d_< FPT > &li2)
Returns the distance between 2 parallel lines (free function)
Definition: homog2d.hpp:10969
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
bool isParallelTo(const Line2d_< FPT2 > &) const
Definition: homog2d.hpp:9228
Line2d_< FPT > getParallelLine(const Point2d_< FPT2 > &) const
Returns an parallel line to the one it is called on, with pt lying on it.
Definition: homog2d.hpp:8968
static HOMOG2D_INUMTYPE & nullAngleValue()
Definition: homog2d.hpp:1205
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4223
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [16/93]

TEST_CASE ( "dist2points"  ,
""  [t_d2p] 
)
874 {
875  Line2d_<NUMTYPE> li(2,1);
876  auto d = li.distTo( Point2d_<NUMTYPE>() );
877  CHECK( d == 0. );
878 
879  auto d2 = li.distTo( Point2d_<NUMTYPE>(4,2) );
880  CHECK( d2 == 0. );
881 
882  CHECK( li.getCoord( GivenCoord::X, 0. ) == 0. );
883  CHECK( li.getCoord( GivenCoord::X, 2. ) == 1. );
884 
885  CHECK( li.getCoord( GivenCoord::Y, 0. ) == 0. );
886  CHECK( li.getCoord( GivenCoord::Y, 1. ) == 2. );
887 
888  Point2d_<NUMTYPE> p1( 3,3);
889  Point2d_<NUMTYPE> p2( 4,4);
890  auto r = std::abs( p1.distTo( p2 ) - std::sqrt(2.) );
891  CHECK( r < thr::nullDistance() );
892 }
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1195
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8831
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4223
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [17/93]

TEST_CASE ( "Homogr constructors"  ,
""  [testHC] 
)
913 {
914  {
915  auto angle = 0.5;
916  Homogr H0,H1( angle ); // set rotation with constructor
917  H0.setRotation( angle );
918  Line2d_<NUMTYPE> li1;
919  Line2d_<NUMTYPE> li2 = H0 * li1;
920  auto angle2 = getAngle( li1, li2 );
921  CHECK( std::fabs(angle2 - angle) < thr::nullAngleValue() );
922 // std::cout << std::setprecision( std::numeric_limits<double>::digits10 ) << std::scientific << "angle2=" << angle2 << " angle=" << angle << "\n";
923  }
924  {
925  Homogr H0( 4. , 7. );
926  CHECK( H0.value( 0, 2 ) == 4. );
927  CHECK( H0.value( 1, 2 ) == 7. );
928  }
929 }
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9204
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10993
const FPT & value(size_t r, size_t c) const
Definition: homog2d.hpp:1473
Hmatrix_ & setRotation(T theta)
Sets the matrix as a rotation with an angle theta (radians)
Definition: homog2d.hpp:1864
static HOMOG2D_INUMTYPE & nullAngleValue()
Definition: homog2d.hpp:1205
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [18/93]

TEST_CASE ( "test Homogr ,
""  [testH] 
)
932 {
933  {
934  Homogr H1,H2;
935  auto H = H1*H2;
936  CHECK( H == H1 );
937  }
938  {
939  std::vector<std::vector<float>> m1a(3);
940  for( auto& li: m1a)
941  li.resize(3,1);
942  Homogr_<NUMTYPE> H1a(m1a);
943 
944  std::vector<std::vector<double>> m1b(3);
945  for( auto& li: m1b)
946  li.resize(3,1);
947  Homogr_<NUMTYPE> H1b(m1b);
948 
949  std::vector<std::vector<int>> m1c(3);
950  for( auto& li: m1c)
951  li.resize(3,1);
952  Homogr_<NUMTYPE> H1c(m1c);
953 
954  std::array<std::array<float,3>,3> m2a;
955  m2a[2][2] = 1.;
956  Homogr_<NUMTYPE> H2a(m2a);
957 
958  std::array<std::array<double,3>,3> m2b;
959  m2b[2][2] = 1.;
960  Homogr_<NUMTYPE> H2b(m2b);
961 
962  std::array<std::array<int,3>,3> m2c;
963  m2c[2][2] = 1.;
964  Homogr_<NUMTYPE> H2c(m2c);
965  }
966  { // test of operator * for points
968  Point2d_<NUMTYPE> pt1(1,1);
969  H.setTranslation( 3., 2. );
970 
971  auto pt2 = H * pt1;
972 
973  CHECK( pt2.getX() == 4. );
974  CHECK( pt2.getY() == 3. );
975 
976  H.setRotation( M_PI/2. );
977  auto pt3 = H * pt1;
978 
979  CHECK( pt3.getX() == Approx( -1. ) );
980  CHECK( pt3.getY() == Approx( 1. ) );
981  }
982  { // test of operator * for container holding points, using applyTo()
984  H.setTranslation(5,6);
985 
986  std::vector<Point2d> v_pt(3); // 3 points at (0,0)
987  H.applyTo( v_pt ); // translate them all to (+5,+6)
988  CHECK( v_pt[2].getX() == 5 );
989  CHECK( v_pt[2].getY() == 6 );
990  CHECK( v_pt[0].getX() == 5 );
991  CHECK( v_pt[0].getY() == 6 );
992  auto v_pt2 = H * v_pt;
993  CHECK( v_pt2.size() == 3 );
994  CHECK( v_pt2[2].getX() == 10 );
995  CHECK( v_pt2[2].getY() == 12 );
996  CHECK( v_pt2[0].getX() == 10 );
997  CHECK( v_pt2[0].getY() == 12 );
998 
999  std::array<Point2d,3> a_pt;
1000  H.applyTo( a_pt );
1001  CHECK( a_pt[2].getX() == 5 );
1002 
1003  std::list<Point2d> l_pt(3);
1004  H.applyTo( l_pt );
1005  CHECK( std::begin(l_pt)->getX() == 5 );
1006  }
1007  { // test of operator * for container holding points
1008  Homogr_<NUMTYPE> H;
1009  H.setTranslation(5,6);
1010 
1011  std::vector<Point2d> v_pt(3);
1012  auto vpt2 = H * v_pt;
1013  CHECK( vpt2.size() == 3 );
1014 
1015  std::array<Point2d,3> a_pt;
1016  auto vpt3 = H * a_pt;
1017  CHECK( vpt3.size() == 3 );
1018 
1019  std::list<Point2d> l_pt(3);
1020  auto vpt4 = H * l_pt;
1021  CHECK( vpt4.size() == 3 );
1022  }
1023 }
Hmatrix_ & setTranslation(T1 tx, T2 ty)
Sets the matrix as a translation tx,ty.
Definition: homog2d.hpp:1840
void applyTo(T &) const
Apply homography to a vector/array/list (type T) of points or lines.
Definition: homog2d.hpp:9563
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
FPT getY(const Point2d_< FPT > &pt)
Definition: homog2d.hpp:9823
Line2d li
Definition: homog2d_test.cpp:4035
FPT getX(const Point2d_< FPT > &pt)
Definition: homog2d.hpp:9820
Hmatrix_ & setRotation(T theta)
Sets the matrix as a rotation with an angle theta (radians)
Definition: homog2d.hpp:1864
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [19/93]

TEST_CASE ( "matrix inversion"  ,
""  [testH3] 
)
1033 {
1035  {
1036  Homogr_<NUMTYPE> HR=H;
1037  HR.inverse();
1038  CHECK( HR == H );
1039  HR.transpose();
1040  CHECK( HR == H );
1041  }
1042 
1043  { // sample inversion
1044 // checked with https://ncalculators.com/matrix/inverse-matrix.htm
1045  H = std::vector<std::vector<double>>{
1046  { 1, -1, 2 },
1047  { 4, 0, 6 },
1048  { 5, 1, -1 }
1049  };
1050 
1051  Homogr_<NUMTYPE> H2;
1052 
1053  H2 = H; // transposing twice = original matrix
1054  H2.transpose();
1055  H2.transpose();
1056  CHECK( H == H2 );
1057 
1058  H2 = H; // transposing twice = original matrix
1059  H2.transpose().transpose();
1060  CHECK( H == H2 );
1061 
1062  H2 = H; // inverting twice = original matrix
1063  H2.inverse();
1064  Homogr_<NUMTYPE> HI = std::vector<std::vector<NUMTYPE>>{
1065  { -3./2, 1./4, -3./2 },
1066  { 17./2, -11./4, 1./2 },
1067  { 1. , -3./2, 1. }
1068  };
1069  CHECK( H2 == HI );
1070  H2.inverse();
1071  CHECK( H == H2 );
1072 
1073  H2 = H; // inverting twice = original matrix
1074  H2.inverse().inverse();
1075  CHECK( H == H2 );
1076 
1077  H2 = H;
1078  H.inverse();
1079  Homogr_<NUMTYPE> HR = std::vector<std::vector<double>>{
1080  { 6, - 1, 6 },
1081  { -34, 11, -2 },
1082  { - 4, 6, -4 }
1083  };
1084  CHECK( HR == H );
1085 
1086  H.transpose();
1087  H2.inverse().transpose();
1088  CHECK( H == H2 );
1089  }
1090 }
Matrix_ & transpose()
Transpose and return matrix.
Definition: homog2d.hpp:1501
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Hmatrix_ & inverse()
Inverse matrix.
Definition: homog2d.hpp:1782
Here is the call graph for this function:

◆ TEST_CASE() [20/93]

TEST_CASE ( "line transformation"  ,
""  [testH3] 
)
1114 {
1115  {
1116  Line2d_<NUMTYPE> d1( 5, 6 ); // line from (0,0) to (5,6)
1117  Point2d_<NUMTYPE> pt1( 5, 6); // point is on line
1118  CHECK( d1.distTo( pt1 ) < g_epsilon );
1119  }
1120  Point2d_<NUMTYPE> pt( 5, 6);
1122  {
1123  H.setTranslation(4,5);
1124  auto d = computeDistTransformedLined( H , pt );
1125  LOCALLOG( "T(4,5): d=" << FullPrecision(d) );
1126  CHECK( d < g_epsilon );
1127  H.setTranslation(4000,5);
1128  auto d2 = computeDistTransformedLined( H , pt );
1129  LOCALLOG( "T(4000,5): d=" << FullPrecision(d2) );
1130  CHECK( d2 < g_epsilon );
1131  H.setTranslation(4,5000);
1132  auto d3 = computeDistTransformedLined( H , pt );
1133  LOCALLOG( "T(4,5000): d=" << FullPrecision(d3) );
1134  CHECK( d3 < g_epsilon );
1135  }
1136  {
1137  H.setRotation( 22.*M_PI/180. );
1138  auto d = computeDistTransformedLined( H , pt );
1139  LOCALLOG( "rotation: d=" << FullPrecision(d) );
1140  CHECK( d < g_epsilon );
1141  }
1142  {
1143  H.setScale(0.4, 4.2);
1144  auto d = computeDistTransformedLined( H , pt );
1145  LOCALLOG( "scale: d=" << FullPrecision(d) );
1146  CHECK( d < g_epsilon );
1147  }
1148  {
1149  H.setRotation( 1.456 ).addTranslation(4,5).addScale( 0.4, 1.2 ); // some random transformation
1150  auto d = computeDistTransformedLined( H , pt );
1151  LOCALLOG( "complex transformation: d=" << FullPrecision(d) );
1152  CHECK( d < g_epsilon );
1153  }
1154 }
Hmatrix_ & setTranslation(T1 tx, T2 ty)
Sets the matrix as a translation tx,ty.
Definition: homog2d.hpp:1840
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Hmatrix_ & setScale(T k)
Sets the matrix as a scaling transformation (same on two axis)
Definition: homog2d.hpp:1897
long double computeDistTransformedLined(Homogr_< NUMTYPE > &H, Point2d_< NUMTYPE > pt1)
Computation of the line passed through H^{-T} and computation of the distance between the resulting l...
Definition: homog2d_test.cpp:1096
#define LOCALLOG(a)
Definition: homog2d_test.cpp:61
Hmatrix_ & addScale(T k)
Adds the same scale factor to the matrix.
Definition: homog2d.hpp:1878
Hmatrix_ & addTranslation(T tx, T ty)
Adds a translation tx,ty to the matrix.
Definition: homog2d.hpp:1830
double g_epsilon
Definition: homog2d_test.cpp:64
std::string FullPrecision(long double d)
Definition: homog2d_test.cpp:1106
Hmatrix_ & setRotation(T theta)
Sets the matrix as a rotation with an angle theta (radians)
Definition: homog2d.hpp:1864
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [21/93]

TEST_CASE ( "matrix chained operations"  ,
""  [testH2] 
)
1157 {
1158  Homogr H1,H2;
1159  CHECK( H1 == H2 );
1160  H1.addTranslation(4,5).addRotation( 1 ).addScale( 5,6);
1161  H2.addRotation( 1 ).addTranslation(4,5).addScale( 5,6);
1162  CHECK( H1 != H2 );
1163 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Hmatrix_ & addScale(T k)
Adds the same scale factor to the matrix.
Definition: homog2d.hpp:1878
Hmatrix_ & addTranslation(T tx, T ty)
Adds a translation tx,ty to the matrix.
Definition: homog2d.hpp:1830
Hmatrix_ & addRotation(T theta)
Adds a rotation with an angle theta (radians) to the matrix.
Definition: homog2d.hpp:1854
Here is the call graph for this function:

◆ TEST_CASE() [22/93]

TEST_CASE ( "getPoints"  ,
""  [test_points] 
)
1166 {
1167  Line2d_<NUMTYPE> liV; // vertical line
1168  auto pp = liV.getPoints( GivenCoord::Y, 0.0, 2.0 ); // get points at a distance 2 from (0,0)
1169  CHECK( pp.first == Point2d_<NUMTYPE>(0,-2) );
1170  CHECK( pp.second == Point2d_<NUMTYPE>(0,+2) );
1171 
1172  pp = liV.getPoints( GivenCoord::Y, 3.0, 2.0 ); // get points at a distance 2 from (0,3)
1173  CHECK( pp.first == Point2d_<NUMTYPE>(0,+1) );
1174  CHECK( pp.second == Point2d_<NUMTYPE>(0,+5) );
1175 
1176  Line2d_<NUMTYPE> liH(1,0); // horizontal line
1177  pp = liH.getPoints( GivenCoord::X, 0.0, 2.0 ); // get points at a distance 2 from (0,0)
1178  CHECK( pp.first == Point2d_<NUMTYPE>(-2,0) );
1179  CHECK( pp.second == Point2d_<NUMTYPE>(+2,0) );
1180 
1181  pp = liH.getPoints( GivenCoord::X, 3.0, 2.0 ); // get points at a distance 2 from (3,0)
1182  CHECK( pp.first == Point2d_<NUMTYPE>(+1,0) );
1183  CHECK( pp.second == Point2d_<NUMTYPE>(+5,0) );
1184 
1185  Line2d_<NUMTYPE> li( 1, 1 ); // line with slope [1,1] starting from (0,0)
1186  auto k = 1.0 / std::sqrt(2.);
1187  pp = li.getPoints( GivenCoord::X, 5.0, 1.0 ); // get points at a distance 1 from (5,0)
1188  CHECK( pp.first == Point2d_<NUMTYPE>( 5-k, 5-k ) );
1189  CHECK( pp.second == Point2d_<NUMTYPE>( 5+k, 5+k ) );
1190 
1191  li = Point2d_<NUMTYPE>(3,1) * Point2d_<NUMTYPE>(4,2); // line with slope [1,1] starting from (3,1)
1192 
1193  pp = li.getPoints( GivenCoord::X, 5.0, 1.0 ); // get points at a distance 2 from (3,0)
1194  CHECK( pp.first == Point2d_<NUMTYPE>( 5-k, 3-k ) );
1195  CHECK( pp.second == Point2d_<NUMTYPE>( 5+k, 3+k ) );
1196 }
PointPair_< FPT > getPoints(GivenCoord gc, FPT2 coord, FPT3 dist) const
Returns a pair of points that are lying on line at distance dist from a point defined by one of its c...
Definition: homog2d.hpp:4085
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [23/93]

TEST_CASE ( "getAngle"  ,
""  [test_angle] 
)
1199 {
1200  Line2d_<NUMTYPE> lid(1,1); // diagonal line going through (0,0)
1201  Line2d_<NUMTYPE> lih(1,0); // horizontal line
1202  Line2d_<NUMTYPE> liv; // vertical line
1203  CHECK( lih.getAngle(lid) == Approx(M_PI/4.) );
1204  CHECK( liv.getAngle(lid) == Approx(M_PI/4.) );
1205  CHECK( liv.getAngle(lih) == Approx(M_PI/2.) );
1206 
1207  CHECK( getAngle(lih,lid) == Approx(M_PI/4.) );
1208  CHECK( getAngle(liv,lid) == Approx(M_PI/4.) );
1209  CHECK( getAngle(lih,liv) == Approx(M_PI/2.) );
1210 // liv.getAngle( Point2d() ); // NO BUILD
1211 // getAngle( liv, Point2d() ); // NO BUILD
1212 }
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9204
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
HOMOG2D_INUMTYPE getAngle(const LPBase< T, FPT2 > &other) const
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [24/93]

TEST_CASE ( "getCorrectPoints"  ,
""  [gcpts] 
)
1216 {
1217  {
1218  auto p1 = detail::getCorrectPoints( Point2d(0,0), Point2d(5,5) );
1219  CHECK( p1.first == Point2d(0,0) );
1220  CHECK( p1.second == Point2d(5,5) );
1221  }
1222  {
1223  auto p1 = detail::getCorrectPoints( Point2d(0,5), Point2d(5,0) );
1224  CHECK( p1.first == Point2d(0,0) );
1225  CHECK( p1.second == Point2d(5,5) );
1226  }
1227  {
1228  auto p1 = detail::getCorrectPoints( Point2d(5,0), Point2d(0,5) );
1229  CHECK( p1.first == Point2d(0,0) );
1230  CHECK( p1.second == Point2d(5,5) );
1231  }
1232  {
1233  auto p1 = detail::getCorrectPoints( Point2d(5,5), Point2d(0,0) );
1234  CHECK( p1.first == Point2d(0,0) );
1235  CHECK( p1.second == Point2d(5,5) );
1236  }
1237 }
PointPair_< FPT > getCorrectPoints(const Point2d_< FPT > &p0, const Point2d_< FPT > &p1)
Private free function, get top-left and bottom-right points from two arbitrary points.
Definition: homog2d.hpp:1312
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [25/93]

TEST_CASE ( "IsInside - manual"  ,
""  [IsInside_man] 
)
1245 {
1246  Point2d pt1(10,10),pt2(10,10);
1247  Line2d li1, li2;
1248  FRect rect1, rect2;
1249  Circle cir1, cir2;
1250  Segment seg1, seg2;
1251  Ellipse ell1(5.,5.), ell2(3,4);
1252  CPolyline cpol1,cpol2;
1253  OPolyline opol1,opol2;
1254 
1255  CHECK( !pt2.isInside( pt1 ) );
1256  CHECK( !pt2.isInside( li1 ) );
1257  CHECK( !pt2.isInside( rect1 ) );
1258  CHECK( !pt2.isInside( cir1 ) );
1259  CHECK( !pt2.isInside( ell1 ) );
1260  CHECK( !pt2.isInside( cpol1 ) );
1261  CHECK( !pt2.isInside( opol1 ) );
1262 
1263  CHECK( !li2.isInside( pt1 ) );
1264  CHECK( !li2.isInside( li1 ) );
1265  CHECK( !li2.isInside( rect1 ) );
1266  CHECK( !li2.isInside( cir1 ) );
1267  CHECK( !li2.isInside( ell1 ) );
1268  CHECK( !li2.isInside( cpol1 ) );
1269  CHECK( !li2.isInside( opol1 ) );
1270 
1271  CHECK( !rect2.isInside( pt1 ) );
1272  CHECK( !rect2.isInside( li1 ) );
1273  CHECK( !rect2.isInside( rect1 ) );
1274  CHECK( !rect2.isInside( cir1 ) );
1275  CHECK( !rect2.isInside( ell1 ) );
1276  CHECK( !rect2.isInside( cpol1 ) );
1277  CHECK( !rect2.isInside( opol1 ) );
1278 
1279  CHECK( !cir2.isInside( pt1 ) );
1280  CHECK( !cir2.isInside( li1 ) );
1281  CHECK( !cir2.isInside( rect1 ) );
1282  CHECK( !cir2.isInside( cir1 ) );
1283  CHECK( !cir2.isInside( ell1 ) );
1284  CHECK( !cir2.isInside( cpol1 ) );
1285  CHECK( !cir2.isInside( opol1 ) );
1286 
1287  CHECK( !seg2.isInside( pt1 ) );
1288  CHECK( !seg2.isInside( li1 ) );
1289  CHECK( !seg2.isInside( rect1 ) );
1290  CHECK( !seg2.isInside( cir1 ) );
1291  CHECK( !seg2.isInside( ell1 ) );
1292  CHECK( !seg2.isInside( cpol1 ) );
1293  CHECK( !seg2.isInside( opol1 ) );
1294 
1295  CHECK( !ell2.isInside( pt1 ) );
1296  CHECK( !ell2.isInside( li1 ) );
1297  CHECK( !ell2.isInside( rect1 ) );
1298  CHECK( !ell2.isInside( cir1 ) );
1299  CHECK( !ell2.isInside( ell1 ) );
1300  CHECK( !ell2.isInside( cpol1 ) );
1301  CHECK( !ell2.isInside( opol1 ) );
1302 
1303  CHECK( !cpol2.isInside( pt1 ) );
1304  CHECK( !cpol2.isInside( li1 ) );
1305  CHECK( !cpol2.isInside( rect1 ) );
1306  CHECK( !cpol2.isInside( cir1 ) );
1307  CHECK( !cpol2.isInside( ell1 ) );
1308  CHECK( !cpol2.isInside( cpol1 ) );
1309  CHECK( !cpol2.isInside( opol1 ) );
1310 
1311  CHECK( !opol2.isInside( pt1 ) );
1312  CHECK( !opol2.isInside( li1 ) );
1313  CHECK( !opol2.isInside( rect1 ) );
1314  CHECK( !opol2.isInside( cir1 ) );
1315  CHECK( !opol2.isInside( ell1 ) );
1316  CHECK( !opol2.isInside( cpol1 ) );
1317  CHECK( !opol2.isInside( opol1 ) );
1318 }
A circle.
Definition: homog2d.hpp:378
bool isInside(const Circle_< FPT2 > &shape) const
Segment is inside Circle.
Definition: homog2d.hpp:5145
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
bool isInside(const T &shape) const
Returns true if rectangle is inside shape (Circle_ or FRect_ or base::Polyline)
Definition: homog2d.hpp:2972
bool isInside(const Circle_< FPT2 > &other) const
Returns true if circle is inside other circle.
Definition: homog2d.hpp:3403
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4346
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
bool isInside(const T &prim) const
Polyline isInside other primitive.
Definition: homog2d.hpp:6596
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [26/93]

TEST_CASE ( "Polyline IsInside Polyline"  ,
""  [tpolipol] 
)
1321 {
1322  { // checking https://github.com/skramm/homog2d/issues/10
1323  CPolyline_<HOMOG2D_INUMTYPE> p1(std::vector<Point2d>{
1324  Point2d(-2, 2),
1325  Point2d(-2,-2),
1326  Point2d( 2,-2),
1327  Point2d( 2, 2),
1328  });
1329  CPolyline_<HOMOG2D_INUMTYPE> p2(std::vector<Point2d>{
1330  Point2d(-5, 5),
1331  Point2d(-5,-5),
1332  Point2d( 5,-5),
1333  Point2d( 5, 5)
1334  });
1335  CHECK( p2.isInside( p1 ) == false );
1336  CHECK( p1.isInside( p2 ) == true );
1337  }
1338  { // one inside the other
1339  #include "figures_test/polyline_inside_a1.code"
1340  CHECK( pl2.isInside( pl ) == false );
1341  CHECK( pl.isInside( pl2 ) == true );
1342  }
1343  { // simple intersection, one point outside
1344  #include "figures_test/polyline_inside_a2.code"
1345  CHECK( pl2.isInside( pl ) == false );
1346  CHECK( pl.isInside( pl2 ) == false );
1347  }
1348  { // nothing common
1349  #include "figures_test/polyline_inside_a3.code"
1350  CHECK( pl2.isInside( pl ) == false );
1351  CHECK( pl.isInside( pl2 ) == false );
1352  }
1353  { // all points inside, but some intersections
1354  #include "figures_test/polyline_inside_a4.code"
1355  CHECK( pl2.isInside( pl ) == false );
1356  CHECK( pl.isInside( pl2 ) == false );
1357  }
1358 
1359  { // Open polyline inside a closed polyline
1360  #include "figures_test/polyline_inside_b1.code"
1361  CHECK( pl2.isInside( pl ) == true );
1362  CHECK( pl.isInside( pl2 ) == false );
1363  }
1364  { // Open polyline inside a closed polyline, but one point outside
1365  #include "figures_test/polyline_inside_b2.code"
1366  CHECK( pl2.isInside( pl ) == false );
1367  CHECK( pl.isInside( pl2 ) == false );
1368  }
1369  { // Open polyline with no common with closed polyline
1370  #include "figures_test/polyline_inside_b3.code"
1371  CHECK( pl2.isInside( pl ) == false );
1372  CHECK( pl.isInside( pl2 ) == false );
1373  }
1374 
1375  { // two Open polylines
1377  {1,2},{1,1},{2,2}
1378  });
1380  {3,3},{3,2},{4,2}
1381  });
1382  CHECK( pl2.isInside( pl ) == false );
1383  CHECK( pl.isInside( pl2 ) == false );
1384  }
1385  { // two Open polylines
1387  {1,1},{5,1},{5,5},{1,5}
1388  });
1390  {3,3},{3,2},{4,2}
1391  });
1392  CHECK( pl2.isInside( pl ) == false );
1393  CHECK( pl.isInside( pl2 ) == false );
1394  }
1395 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [27/93]

TEST_CASE ( "Point2d IsInside Polyline"  ,
""  [tptipol] 
)
1398 {
1400 
1401  OPolyline_<HOMOG2D_INUMTYPE> opol{ std::vector<Point2d>{ {0,0}, {3,4}, {1,8} } };
1402  CHECK( !pt.isInside( opol ) );
1403 
1404  {
1405  CPolyline_<HOMOG2D_INUMTYPE> cpol{ FRect_<HOMOG2D_INUMTYPE>() }; // polygon (0,0)-(1,0)-(1,1)-(0,1)
1406 
1407  pt.set( 0, 0 );
1408  CHECK( !pt.isInside( cpol ) ); // equal to one of the points
1409  pt.set( .2, .3 );
1410  CHECK( pt.isInside( cpol ) );
1411  pt.set( 1,0 );
1412  CHECK( !pt.isInside( cpol ) );
1413  pt.set( .5, 0. );
1414  CHECK( !pt.isInside( cpol ) );
1415  }
1416  {
1417 // CPolyline_<HOMOG2D_INUMTYPE> cpol{ {1,0},{2,1},{1,2},{0,1} };
1418  CPolyline_<HOMOG2D_INUMTYPE> cpol{ std::vector<Point2d>{ {1,0},{2,1},{1,2},{0,1} } };
1419 
1420  pt.set( 1,1 );
1421  CHECK( pt.isInside( cpol ) );
1422  }
1423 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
CPolyline cpol
Definition: homog2d_test.cpp:4030
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4346
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [28/93]

TEST_CASE ( "Line2d IsInside something"  ,
""  [tlir] 
)
1427 {
1428  Point2d_<NUMTYPE> pt1(2,10);
1429  Point2d_<NUMTYPE> pt2(10,2);
1430  auto li = pt1*pt2;
1431  CHECK( li.isInside( pt1, pt2 ) == false );
1432 
1433  Circle_<NUMTYPE> c( 4, 5, 2 );
1434  CHECK( li.isInside( c ) == false );
1435 
1436  Ellipse_<NUMTYPE> ell(pt1);
1437  CHECK( li.isInside( ell ) == false );
1438 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Ellipse ell
Definition: homog2d_test.cpp:4037
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4346
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [29/93]

TEST_CASE ( "Point2d IsInside Circle ,
""  [tptic] 
)
1441 {
1442  Circle_<NUMTYPE> c1(10.);
1443  Circle_<NUMTYPE> c2(2.);
1444  {
1445  Point2d p1( 3,3 ); // point inside circle
1446  CHECK( p1.isInside(c1) );
1447  CHECK( !p1.isInside(c2) );
1448  CHECK( p1.isInside( Point2d(0,0), 8 ) );
1449  CHECK( !p1.isInside( Point2d(0,0), 2 ) );
1450  }
1451  {
1452  Point2d p1( 10, 0 ); // point on the edge of circle
1453  CHECK( !p1.isInside(c1) );
1454  Point2d p2( 0, 10 ); // point on the edge of circle
1455  CHECK( !p2.isInside(c1) );
1456  }
1457 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [30/93]

TEST_CASE ( "Point2d IsInside FRect ,
""  [tptir] 
)
1460 {
1461  Point2d_<NUMTYPE> pt1(2,10);
1462  Point2d_<NUMTYPE> pt2(10,2);
1463 
1464 // Line2d_<NUMTYPE> li; // THIS DOES NOT BUILD (on purpose)
1465 // li.isInside( pt1, pt2 ); // (but we can't test this...)
1466 
1467  Point2d_<NUMTYPE> pt; // (0,0)
1468  CHECK( pt.isInside( pt1, pt2 ) == false );
1469  pt.set(5,5);
1470  CHECK( pt.isInside( pt1, pt2 ) == true );
1471 
1472  pt.set(10,5); // on the edge
1473  CHECK( pt.isInside( pt1, pt2 ) == false );
1474  pt.set(5,10);
1475  CHECK( pt.isInside( pt1, pt2 ) == false );
1476 
1477  pt.set(4.999,9.99);
1478  CHECK( pt.isInside( pt1, pt2 ) == true );
1479 
1480  CHECK( Point2d_<NUMTYPE>( 2, 2).isInside( pt1, pt2 ) == false );
1481  CHECK( Point2d_<NUMTYPE>( 2,10).isInside( pt1, pt2 ) == false );
1482  CHECK( Point2d_<NUMTYPE>(10, 2).isInside( pt1, pt2 ) == false );
1483  CHECK( Point2d_<NUMTYPE>(10,10).isInside( pt1, pt2 ) == false );
1484 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4346
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [31/93]

TEST_CASE ( "Segment IsInside FRect ,
""  [tsir] 
)
1487 {
1488  FRect_<NUMTYPE> r(2,3, 10,10);
1489  CHECK( r.length() == 30 );
1490  CHECK( r.area() == 56 );
1491  CHECK( r.width() == 8 );
1492  CHECK( r.height() == 7 );
1493 
1494  CHECK( Segment_<NUMTYPE>( 0,0, 5,0 ).isInside( r ) == false ); // outside
1495  CHECK( Segment_<NUMTYPE>( 2,5, 4,5 ).isInside( r ) == false ); // on the contour
1496  CHECK( Segment_<NUMTYPE>( 2.00001, 5., 4.,5. ).isInside( r ) == true );
1497  CHECK( Segment_<NUMTYPE>( 3,5, 4,5 ).isInside( r ) == true );
1498 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [32/93]

TEST_CASE ( "Circle IsInside FRect ,
""  [tcir] 
)
1501 {
1502  FRect_<NUMTYPE> r(2,3, 10,10);
1503  CHECK( Circle_<NUMTYPE>( 5,5, 2 ).isInside( r ) == false ); // touches rectangle at (5,3)
1504  CHECK( Circle_<NUMTYPE>( 5,5, 1 ).isInside( r ) == true );
1505  CHECK( Circle_<NUMTYPE>( 6,6, 2 ).isInside( r ) == true );
1506  CHECK( Circle_<NUMTYPE>().isInside( r ) == false );
1507 
1508  CHECK( Circle( 6,6, 22 ).isInside( r ) == false);
1509  CHECK( r.isInside( Circle( 6,6, 22 ) ) == true );
1510 
1511  std::vector<Point2d> vecpt{ {3,3},{4,4} };
1512  CPolyline pl(vecpt);
1513  CHECK( pl.isInside( r ) == false ); // on contour
1514 }
A circle.
Definition: homog2d.hpp:378
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [33/93]

TEST_CASE ( "Circle IsInside Circle ,
""  [tcic] 
)
1537 {
1538  Circle_<NUMTYPE> c1(10.);
1539  Circle_<NUMTYPE> c2(2.);
1540  {
1541  CHECK( c2.isInside(c1) ); // circle inside circle
1542  CHECK( !c1.isInside(c2) );
1543  CHECK( !c1.isInside(c1) );
1544  CHECK( c1 != c2 );
1545  CHECK( c1 == c1 );
1546  }
1547  {
1548  Circle_<NUMTYPE> cA( Point2d(), 10.);
1549  CHECK( cA.radius() == 10. );
1550  cA.radius() = 12;
1551  CHECK( cA.radius() == 12. );
1552  CHECK( cA.center() == Point2d(0,0) );
1553 
1554  Circle_<NUMTYPE> cB( Point2d(5,0), 2.);
1555  auto seg = getSegment( cA, cB );
1556  CHECK( seg.getPts().first == Point2d(0,0) );
1557  CHECK( seg.getPts().second == Point2d(5,0) );
1558  CHECK( seg.length() == 5 );
1559  }
1560 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Segment_< typename T1::FType > getSegment(const T1 &c1, const T2 &c2)
Free function, returns segment between two circle centers (or ellipse)
Definition: homog2d.hpp:10688
HOMOG2D_INUMTYPE length() const
Get segment length.
Definition: homog2d.hpp:5047
PointPair_< FPT > getPts() const
Returns the points of segment as a std::pair.
Definition: homog2d.hpp:5197
Here is the call graph for this function:

◆ TEST_CASE() [34/93]

TEST_CASE ( "Intersection"  ,
""  [int_all] 
)
1569 {
1570  FRect r1,r2;
1571  Circle c1,c2;
1572  Segment s1,s2;
1573  Line2d l1,l2;
1574  OPolyline po1,po2;
1575  CPolyline pc1,pc2;
1576 
1577  CHECK( !r1.intersects( r2 )() ); // intersection with object of same type
1578  CHECK( !c1.intersects( c2 )() );
1579  CHECK( !s1.intersects( s2 )() );
1580  CHECK( !l1.intersects( l2 )() );
1581  CHECK( !po1.intersects( po2 )() );
1582  CHECK( !pc1.intersects( pc2 )() );
1583 
1584  CHECK( r1.intersects( c2 )() );
1585  CHECK( r1.intersects( s2 )() );
1586  CHECK( r1.intersects( l2 )() );
1587  CHECK( !r1.intersects( po2 )() ); // polyline is empty, so no intersection
1588  CHECK( !r1.intersects( pc2 )() ); // polyline is empty, so no intersection
1589 
1590  CHECK( c1.intersects( r2 )() );
1591  CHECK( c1.intersects( s2 )() );
1592  CHECK( c1.intersects( l2 )() );
1593  CHECK( !c1.intersects( po2 )() ); // polyline is empty, so no intersection
1594  CHECK( !c1.intersects( pc2 )() ); // polyline is empty, so no intersection
1595 
1596  CHECK( s1.intersects( r2 )() );
1597  CHECK( s1.intersects( c2 )() );
1598  CHECK( s1.intersects( l2 )() );
1599  CHECK( !s1.intersects( po2 )() ); // polyline is empty, so no intersection
1600  CHECK( !s1.intersects( pc2 )() ); // polyline is empty, so no intersection
1601 
1602  CHECK( l1.intersects( r2 )() );
1603  CHECK( l1.intersects( c2 )() );
1604  CHECK( l1.intersects( s2 )() );
1605  CHECK( !l1.intersects( po2 )() ); // polyline is empty, so no intersection
1606  CHECK( !l1.intersects( pc2 )() ); // polyline is empty, so no intersection
1607 
1608  CHECK( !po1.intersects( r2 )() );
1609  CHECK( !po1.intersects( c2 )() );
1610  CHECK( !po1.intersects( s2 )() );
1611  CHECK( !po1.intersects( l2 )() );
1612  CHECK( !po1.intersects( pc2 )() );
1613 
1614  CHECK( !pc1.intersects( r2 )() );
1615  CHECK( !pc1.intersects( c2 )() );
1616  CHECK( !pc1.intersects( s2 )() );
1617  CHECK( !pc1.intersects( l2 )() );
1618  CHECK( !pc1.intersects( po2 )() );
1619 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::Intersect< detail::Inters_1, FPT > intersects(const SegVec< SV2, FPT2 > &) const
Segment/Segment intersection.
Definition: homog2d.hpp:8205
detail::IntersectM< FPT > intersects(const T &other) const
Polyline intersection with Line, Segment, FRect, Circle.
Definition: homog2d.hpp:6568
detail::IntersectM< FPT > intersects(const Line2d_< FPT2 > &line) const
FRect/Line intersection.
Definition: homog2d.hpp:3012
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4285
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
detail::Intersect< detail::Inters_2, FPT > intersects(const Line2d_< FPT2 > &li) const
Circle/Line intersection.
Definition: homog2d.hpp:3434
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [35/93]

TEST_CASE ( "Line/Line intersection"  ,
""  [int_LL] 
)
1623 {
1624  Line2d_<NUMTYPE> liv1,liv3;
1625  Line2d_<NUMTYPE> liv2( Point2d(5,0), Point2d(5,10) );
1626  Line2d_<NUMTYPE> lih( Point2d(0,0), Point2d(1,0) );
1627  CHECK( liv1.intersects( lih )() );
1628  CHECK( !liv1.intersects( liv2 )() );
1629  CHECK( lih.intersects( liv2 )() );
1630  CHECK( !liv1.intersects( liv3 )() );
1631 
1632  auto i1 = liv1.intersects( lih );
1633  auto i2 = liv1.intersects( liv2 );
1634  auto i3 = lih.intersects( liv2 );
1635 
1636  CHECK( i1() );
1637  CHECK( !i2() );
1638  CHECK( i3() );
1639 
1640  CHECK( i1.size()==1 );
1641  CHECK( i2.size()==0 );
1642  CHECK( i3.size()==1 );
1643 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4285
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [36/93]

TEST_CASE ( "Segment/Segment intersection"  ,
""  [int_SS] 
)
1646 {
1647  Segment_<NUMTYPE> s1,s2;
1648  {
1649  CHECK( s1 == s2 );
1650  auto si = s1.intersects(s2);
1651  CHECK( si() == false );
1652  CHECK( si.size() == 0 );
1653  }
1654  {
1655  s1.set( Point2d(0,0), Point2d(4,4) ); // diagonal
1656  s2.set( Point2d(0,4), Point2d(4,0) );
1657  auto si = s1.intersects(s2);
1658  CHECK( si() == true );
1659  CHECK( si.size() == 1 );
1660  CHECK( si.get() == Point2d(2,2) );
1661  }
1662  {
1663  s1.set( Point2d(0,0), Point2d(10,0) ); // overlapping (complete
1664  s2.set( Point2d(5,0), Point2d(15,0) );
1665  auto si = s1.intersects(s2);
1666  CHECK( si() == false );
1667  CHECK( si.size() == 0 );
1668  }
1669  {
1670  s1.set( Point2d(0,0), Point2d(0,1) ); // vertical
1671  s2.set( Point2d(1,1), Point2d(0,1) ); // horizontal
1672  auto si = s1.intersects(s2);
1673  CHECK( si() );
1674  CHECK( si.size() == 1 );
1675  CHECK( si.get() == Point2d(0,1) );
1676  }
1677  {
1678  s1.set( Point2d(0,0), Point2d(0,2) ); // vertical
1679 
1680  s2.set( Point2d(1,1), Point2d(0,1) ); // horizontal, touches the other one in the middle
1681  {
1682  auto si = s1.intersects(s2);
1683  CHECK( si() );
1684  CHECK( si.size() == 1 );
1685  CHECK( si.get() == Point2d(0,1) );
1686  }
1687  s2.set( Point2d(0,0), Point2d(1,0) ); // horizontal, touches the edge of other one
1688  {
1689  auto si = s1.intersects(s2);
1690  CHECK( si() );
1691  CHECK( si.size() == 1 );
1692  CHECK( si.get() == Point2d(0,0) );
1693  }
1694  s2.set( Point2d(1,1), Point2d(0,1) ); // horizontal, touches the edge of other one
1695  {
1696  auto si = s1.intersects(s2);
1697  CHECK( si() );
1698  CHECK( si.size() == 1 );
1699  CHECK( si.get() == Point2d(0,1) );
1700  }
1701  s2.set( Point2d(-1,1), Point2d(0,1) ); // horizontal, touches the edge of other one
1702  {
1703  auto si = s1.intersects(s2);
1704  CHECK( si() );
1705  CHECK( si.size() == 1 );
1706  CHECK( si.get() == Point2d(0,1) );
1707  }
1708  }
1709  {
1710  s1.set( 0., 0., 1., 0. );
1711  s2.set( 1., 1., 1., -1E-05 );
1712  {
1713  auto si = s1.intersects(s2);
1714  CHECK( si() );
1715  CHECK( si.size() == 1 );
1716  CHECK( si.get() == Point2d(1,0) );
1717  }
1718  s2.set( 1., 1., 1., +1E-05 );
1719  {
1720  CHECK( !s1.intersects(s2)() );
1721  }
1722  }
1723 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::Intersect< detail::Inters_1, FPT > intersects(const SegVec< SV2, FPT2 > &) const
Segment/Segment intersection.
Definition: homog2d.hpp:8205
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
void set(const Point2d_< FP1 > &p1, const Point2d_< FP2 > &p2)
Setter.
Definition: homog2d.hpp:4960
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [37/93]

TEST_CASE ( "Circle/Circle intersection"  ,
""  [int_CC] 
)
1726 {
1727  {
1728  Circle_<NUMTYPE> cA, cB;
1729  CHECK( cA == cB ); // identical circles do
1730  CHECK( !cA.intersects(cB)() ); // not intersect
1731  }
1732  {
1733  Circle_<NUMTYPE> cA;
1734  Circle_<NUMTYPE> cB( Point2d(5,5), 2 );
1735  CHECK( cA != cB );
1736  CHECK( !cA.intersects(cB)() );
1737  }
1738  {
1739  Circle_<NUMTYPE> cA( Point2d(0,0), 2 );
1740  Circle_<NUMTYPE> cB( Point2d(3,0), 2 );
1741  CHECK( cA != cB );
1742  CHECK( cA.intersects(cB)() );
1743  CHECK( cA.intersects(cB).size() == 2 );
1744  }
1745  {
1746  Circle_<NUMTYPE> cA( Point2d(0,0), 1 );
1747  Circle_<NUMTYPE> cB( Point2d(2,0), 1 );
1748  CHECK( cA != cB );
1749  CHECK( cA.intersects(cB)() );
1750  auto inter = cA.intersects(cB);
1751  CHECK( inter() == true );
1752  CHECK( inter.size() == 1 );
1753 // CHECK( inter.get().first == Point2d(1,0) );
1754 // CHECK( inter.get().second == Point2d(1,0) );
1755  CHECK( inter.get()[0] == Point2d(1,0) );
1756  }
1757 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
detail::Intersect< detail::Inters_2, FPT > intersects(const Line2d_< FPT2 > &li) const
Circle/Line intersection.
Definition: homog2d.hpp:3434
Here is the call graph for this function:

◆ TEST_CASE() [38/93]

TEST_CASE ( "FRect/FRect intersection"  ,
""  [int_FF] 
)
1765 {
1766  { // identical rectangles
1767  FRect_<NUMTYPE> r1, r2;
1768  CHECK( r1 == r2 );
1769  CHECK( !r1.intersects(r2)() ); // no intersection !
1770  auto inters = r1.intersects(r2);
1771  CHECK( inters.size() == 0 );
1772 
1773  auto i1 = intersectArea(r1,r2);
1774  CHECK( i1() == true );
1775  CHECK( i1.get() == r1 );
1776 
1777  auto u1 = unionArea(r1,r2);
1778  CHECK( u1.size() == 4 ); // 4 points
1779  CHECK( u1 == CPolyline(r1) ); // same
1780  }
1781  {
1782 #include "figures_test/frect_intersect_1.code"
1783  CHECK( r1 != r2 );
1784  CHECK( r1.height() == r2.height() );
1785  CHECK( !r1.intersects(r2)() );
1786  auto inters = r1.intersects(r2);
1787  CHECK( inters.size() == 0 );
1788 
1789  auto a = r1.intersectArea(r2);
1790  CHECK( a() == false ); // no intersection !
1791  auto b = r1&r2;
1792  CHECK( b() == false ); // no intersection !
1793 
1794  auto u1 = unionArea(r1,r2);
1795  CHECK( u1.size() == 0 ); // empty
1796  }
1797  {
1798 #include "figures_test/frect_intersect_2.code"
1799  CHECK( r1 != r2 );
1800  CHECK( r1.width() == r2.width() );
1801  CHECK( r1.height() == r2.height() );
1802  CHECK( r1.intersects(r2)() );
1803  auto inters = r1.intersects(r2);
1804  CHECK( inters.size() == 2 );
1805  auto vpts = inters.get();
1806  CHECK( vpts[0] == Point2d(2,2) );
1807  CHECK( vpts[1] == Point2d(3,1) );
1808 
1809  auto rect_inter = r1.intersectArea(r2);
1810  CHECK( rect_inter() == true );
1811  CHECK( rect_inter.get() == FRect(2,1, 3,2) );
1812  auto rect_inter2 = r1&r2;
1813  CHECK( rect_inter2() == true );
1814  CHECK( rect_inter2.get() == FRect(2,1, 3,2) );
1815 
1816  auto u1 = unionArea(r1,r2);
1817 // Polyline p{ [0,0],[1,1] };
1818  CHECK( u1.size() == 8 );
1819  }
1820 
1821  { // 4 intersection points
1822 #include "figures_test/frect_intersect_3.code"
1823  CHECK( r1 != r2 );
1824  CHECK( r1.intersects(r2)() );
1825  auto inters = r1.intersects(r2);
1826  CHECK( inters.size() == 4 );
1827  auto vpts = inters.get();
1828  CHECK( vpts[0] == Point2d(2,2) );
1829  CHECK( vpts[1] == Point2d(2,4) );
1830  CHECK( vpts[2] == Point2d(4,2) );
1831  CHECK( vpts[3] == Point2d(4,4) );
1832 
1833  auto rect_inter = r1.intersectArea(r2);
1834  CHECK( rect_inter() == true );
1835  CHECK( rect_inter.get() == FRect(2,2, 4,4) );
1836 
1837  auto u1 = unionArea(r1,r2);
1838 // Polyline p{ [0,0],[1,1] };
1839  CHECK( u1.size() == 12 );
1840  }
1841 
1842  { // horizontal segment overlap
1843 #include "figures_test/frect_intersect_4.code"
1844  CHECK( r1 != r2 );
1845  CHECK( r1.width() == r2.width() );
1846  CHECK( r1.height() == r2.height() );
1847  CHECK( r1.intersects(r2)() );
1848  auto inters = r1.intersects(r2);
1849  CHECK( inters.size() == 4 );
1850  auto vpts = inters.get();
1851  CHECK( vpts[0] == Point2d(3,1) );
1852  CHECK( vpts[1] == Point2d(3,3) );
1853  CHECK( vpts[2] == Point2d(4,1) );
1854  CHECK( vpts[3] == Point2d(4,3) );
1855 
1856  auto rect_inter = r1.intersectArea(r2);
1857  CHECK( rect_inter() == true );
1858  CHECK( rect_inter.get() == FRect(3,1, 4,3) );
1859 
1860  auto u1 = unionArea(r1,r2);
1861 // Polyline p{ [0,0],[1,1] };
1862  CHECK( u1.size() == 4 );
1863  }
1864  { // common vertical segment
1865 #include "figures_test/frect_intersect_5.code"
1866  CHECK( r1 != r2 );
1867  CHECK( r1.width() != r2.width() );
1868  CHECK( r1.height() == r2.height() );
1869  CHECK( r1.intersects(r2)() );
1870  auto inters = r1.intersects(r2);
1871  CHECK( inters() == true );
1872  CHECK( inters.size() == 2 );
1873  auto vpts = inters.get();
1874  CHECK( vpts[0] == Point2d( 3,0 ) );
1875  CHECK( vpts[1] == Point2d( 3,2 ) );
1876  CHECK( r1.intersectArea(r2)() == false ); // no area intersection
1877 
1878  r2.translate( 0.000001, 0 ); // move it a bit left
1879  inters = r1.intersects(r2); // => no more intersection
1880  CHECK( inters() == false );
1881  CHECK( inters.size() == 0 );
1882  CHECK( r1.intersectArea(r2)() == false ); // still no intersection
1883 
1884  auto u1 = unionArea(r1,r2);
1885  CHECK( u1.size() == 0 );
1886  }
1887  { // two rectangles joined by corner at 3,2
1888 #include "figures_test/frect_intersect_6.code"
1889  CHECK( r1.intersects(r2)() );
1890  auto inters = r1.intersects(r2);
1891  CHECK( inters.size() == 1 );
1892  auto vpts = inters.get();
1893  CHECK( vpts[0] == Point2d( 3,2 ) );
1894  CHECK( r1.intersectArea(r2)() == false ); // only one point !
1895 
1896  auto u1 = unionArea(r1,r2);
1897  CHECK( u1.size() == 8 );
1898  }
1899  { // two rectangles
1900 #include "figures_test/frect_intersect_7.code"
1901  CHECK( r1.intersects(r2)() );
1902  auto inters = r1.intersects(r2);
1903  CHECK( inters.size() == 2 );
1904  auto vpts = inters.get();
1905  CHECK( vpts[0] == Point2d( 2,2 ) );
1906  CHECK( vpts[1] == Point2d( 4,2 ) );
1907 
1908  auto rect_inter = r1.intersectArea(r2);
1909  CHECK( rect_inter() == true );
1910  CHECK( rect_inter.get() == FRect(2,2, 4,3) );
1911  }
1912  { // two rectangles with a single common segment
1913 #include "figures_test/frect_intersect_8.code"
1914  CHECK( r1.intersects(r2)() );
1915  auto inters = r1.intersects(r2);
1916  CHECK( inters.size() == 3 );
1917  auto vpts = inters.get();
1918  CHECK( vpts[0] == Point2d( 3,3 ) );
1919  CHECK( vpts[1] == Point2d( 4,2 ) );
1920  CHECK( vpts[2] == Point2d( 4,3 ) );
1921 // auto rect_inter = r1.intersectArea(r2);
1922 // CHECK( rect_inter == FRect(3,2, 4,3) );
1923  }
1924  { // two rectangles with a single common segment
1925 #include "figures_test/frect_intersect_9.code"
1926  CHECK( r1.intersects(r2)() );
1927  auto inters = r1.intersects(r2);
1928  CHECK( inters.size() == 3 );
1929  auto vpts = inters.get();
1930  CHECK( vpts[0] == Point2d( 3,3 ) );
1931  CHECK( vpts[1] == Point2d( 4,2 ) );
1932  CHECK( vpts[2] == Point2d( 4,3 ) );
1933 // auto rect_inter = r1.intersectArea(r2);
1934 // CHECK( rect_inter == FRect(3,2, 4,3) );
1935  }
1936 
1937  { // one rectangle inside the other
1938 #include "figures_test/frect_intersect_10.code"
1939  CHECK( r1.intersects(r2)() == false );
1940  auto inters = r1.intersects(r2);
1941  CHECK( inters.size() == 0 );
1942  auto inters2 = r1.intersectArea(r2);
1943  CHECK( inters2() == true );
1944  CHECK( inters2.get() == r2 );
1945  }
1946  { // one rectangle inside the other, with a common segment
1947 #include "figures_test/frect_intersect_11.code"
1948  CHECK( r1.intersects(r2)() == true );
1949  auto inters = r1.intersects(r2);
1950  CHECK( inters.size() == 2 );
1951  auto vpts = inters.get();
1952  CHECK( vpts[0] == Point2d( 2,3 ) );
1953  CHECK( vpts[1] == Point2d( 3,3 ) );
1954  CHECK( r1.intersectArea(r2)() == true );
1955  auto inter=r1.intersectArea(r2);
1956  CHECK( inter.get() == r2 );
1957  }
1958 
1959 // this below needs to be expanded
1960  {
1961 #include "figures_test/frect_intersect_12.code"
1962  CHECK( r1.intersects(r2)() == true );
1963  auto inters = r1.intersects(r2);
1964  CHECK( inters.size() == 3 );
1965  auto vpts = inters.get();
1966 // priv::printVector( vpts, "intersection points demo12" );
1967  CHECK( vpts[0] == Point2d( 2,0 ) );
1968  CHECK( vpts[1] == Point2d( 2,2 ) );
1969  CHECK( vpts[2] == Point2d( 3,0 ) );
1970  CHECK( r1.intersectArea(r2)() == true );
1971 // auto inter=r1.intersectArea(r2);
1972 // CHECK( inter.get() == r2 );
1973  }
1974 
1975 // this below needs to be expanded
1976  {
1977 #include "figures_test/frect_intersect_13.code"
1978  CHECK( r1.intersects(r2)() == true );
1979  auto inters = r1.intersects(r2);
1980  CHECK( inters.size() == 2 );
1981  auto vpts = inters.get();
1982  CHECK( vpts[0] == Point2d( 3,0 ) );
1983  CHECK( vpts[1] == Point2d( 3,2 ) );
1984  CHECK( r1.intersectArea(r2)() == false );
1985 // auto inter=r1.intersectArea(r2);
1986 // CHECK( inter.get() == r2 );
1987  }
1988 }
CPolyline_< FPT1 > unionArea(const FRect_< FPT1 > &r1, const FRect_< FPT2 > &r2)
Free function, see FRect_::unionArea()
Definition: homog2d.hpp:9868
detail::RectArea< FPT1 > intersectArea(const FRect_< FPT1 > &r1, const FRect_< FPT2 > &r2)
Free function, see FRect_::intersectArea()
Definition: homog2d.hpp:9877
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::RectArea< FPT > intersectArea(const FRect_< FPT2 > &other) const
Returns Rectangle of the intersection area of two rectangles.
Definition: homog2d.hpp:7713
detail::IntersectM< FPT > intersects(const Line2d_< FPT2 > &line) const
FRect/Line intersection.
Definition: homog2d.hpp:3012
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12398
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
HOMOG2D_INUMTYPE width() const
Definition: homog2d.hpp:2746
HOMOG2D_INUMTYPE height() const
Definition: homog2d.hpp:2745
Here is the call graph for this function:

◆ TEST_CASE() [39/93]

TEST_CASE ( "IoU of 2 rectangles"  ,
""  [IOU_RECT] 
)
1991 {
1992  FRect_<NUMTYPE> r1( 0,0,1,1 );
1993  FRect_<NUMTYPE> r2( 2,2,3,3 );
1994  CHECK( IoU(r1,r2) == 0. );
1995  r1.set(0,0,2,2);
1996  CHECK( IoU(r1,r2) == 0. );
1997 
1998  r2.set(1,0,3,2);
1999  CHECK( IoU(r1,r2) == Approx(1./3.) );
2000 }
HOMOG2D_INUMTYPE IoU(const FRect_< FPT1 > &r1, const FRect_< FPT2 > &r2)
Intersection area over Union area (free function)
Definition: homog2d.hpp:9856
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
Here is the call graph for this function:

◆ TEST_CASE() [40/93]

TEST_CASE ( "Circle/Segment intersection"  ,
""  [int_CS] 
)
2003 {
2004  Circle_<NUMTYPE> c1( Point2d(1,1), 1 ); // circle centered on 1,1, going horizontally from 0 to 2 at y=0
2005  {
2006  Segment_<NUMTYPE> s1( Point2d(0,20),Point2d(2,20) ); // horizontal segment at y=20
2007 
2008  CHECK( !c1.intersects( s1 )() );
2009  CHECK( !s1.intersects( c1 )() );
2010  auto int_a = c1.intersects( s1 );
2011  auto int_b = s1.intersects( c1 );
2012  CHECK( !int_a() );
2013  CHECK( !int_b() );
2014  CHECK( int_a.size() == 0 );
2015  CHECK( int_b.size() == 0 );
2016 
2017  Segment_<NUMTYPE> s2( Point2d(10,0),Point2d(10,20) ); // vertical segment at x=10
2018  CHECK( !c1.intersects( s2 )() );
2019  CHECK( !s2.intersects( c1 )() );
2020  auto int_a2 = c1.intersects( s2 );
2021  auto int_b2 = s2.intersects( c1 );
2022  CHECK( int_a2.size() == 0 );
2023  CHECK( int_b2.size() == 0 );
2024  CHECK( !int_a2() );
2025  CHECK( !int_b2() );
2026  }
2027  {
2028  Segment_<NUMTYPE> s2( Point2d(-5,1),Point2d(+5,1) ); // horizontal segment at y=1
2029 
2030  CHECK( c1.intersects( s2 )() );
2031  CHECK( s2.intersects( c1 )() );
2032 
2033  auto int_a = c1.intersects( s2 );
2034  auto int_b = s2.intersects( c1 );
2035  CHECK( int_a() );
2036  CHECK( int_b() );
2037  CHECK( int_a.size() == 2 );
2038  CHECK( int_b.size() == 2 );
2039  CHECK( int_a.get()[0] == Point2d_<NUMTYPE>(0,1) );
2040  CHECK( int_b.get()[1] == Point2d_<NUMTYPE>(2,1) );
2041  }
2042  {
2043  Segment_<NUMTYPE> s2( Point2d(-5,1),Point2d(1,1) ); // horizontal segment at y=1
2044 
2045  CHECK( c1.intersects( s2 )() );
2046  CHECK( s2.intersects( c1 )() );
2047 
2048  auto int_a = c1.intersects( s2 );
2049  auto int_b = s2.intersects( c1 );
2050  CHECK( int_a() );
2051  CHECK( int_b() );
2052  CHECK( int_a.size() == 1 );
2053  CHECK( int_b.size() == 1 );
2054  CHECK( int_a.get()[0] == Point2d_<NUMTYPE>(0,1) );
2055  }
2056  {
2057  Segment_<NUMTYPE> s2( Point2d(2,0),Point2d(4,0) ); // horizontal segment at y=0, outside circle
2058 
2059  CHECK( !c1.intersects( s2 )() );
2060  CHECK( !s2.intersects( c1 )() );
2061 
2062  auto int_a = c1.intersects( s2 );
2063  auto int_b = s2.intersects( c1 );
2064  CHECK( int_a() == false );
2065  CHECK( int_b() == false );
2066  CHECK( int_a.size() == 0 );
2067  CHECK( int_b.size() == 0 );
2068  }
2069  {
2070  Segment_<NUMTYPE> s2( Point2d(2,1),Point2d(4,1) ); // horizontal segment at y=0, touching edge of circle at (1,1)
2071 
2072  CHECK( c1.intersects( s2 )() );
2073  CHECK( s2.intersects( c1 )() );
2074 
2075  auto int_a = c1.intersects( s2 );
2076  auto int_b = s2.intersects( c1 );
2077  CHECK( int_a() );
2078  CHECK( int_b() );
2079  CHECK( int_a.size() == 1 );
2080  CHECK( int_b.size() == 1 );
2081  CHECK( int_a.get()[0] == Point2d_<NUMTYPE>(2,1) );
2082  }
2083 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [41/93]

TEST_CASE ( "Circle/FRect intersection"  ,
""  [int_CF] 
)
2086 {
2087  {
2088 //#include "figures_test/circle_intersect_1.code"
2089  Circle_<NUMTYPE> r1( Point2d(1,1), 1 );
2090  FRect_<NUMTYPE> r2( Point2d(3,2), Point2d(4,3) );
2091  CHECK( r1.intersects(r2)() == false );
2092  auto inters = r1.intersects(r2);
2093  CHECK( inters.size() == 0 );
2094  }
2095  {
2096 //#include "figures_test/circle_intersect_2.code"
2097  Circle_<NUMTYPE> r1( Point2d(3,3), 2 );
2098  FRect_<NUMTYPE> r2( Point2d(3,2), Point2d(4,3) );
2099  CHECK( r1.intersects(r2)() == false );
2100  }
2101  {
2102  Circle_<NUMTYPE> r1;
2103  FRect_<NUMTYPE> r2( 0,0, 3,3 );
2104  CHECK( r1.intersects(r2)() == true );
2105  auto inters = r1.intersects(r2);
2106  CHECK( inters.size() == 2 );
2107  auto vpts = inters.get();
2108  CHECK( vpts[0] == Point2d( 0,1 ) );
2109  CHECK( vpts[1] == Point2d( 1,0 ) );
2110  }
2111  {
2112  Circle_<NUMTYPE> r1; // (0,0) with radius=1
2113  FRect_<NUMTYPE> r2( 1,0, 3,3 );
2114  CHECK( r1.intersects(r2)() == true );
2115  auto inters = r1.intersects(r2);
2116  CHECK( inters.size() == 1 );
2117  auto vpts = inters.get();
2118  CHECK( vpts[0] == Point2d( 1,0 ) );
2119  }
2120 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
detail::Intersect< detail::Inters_2, FPT > intersects(const Line2d_< FPT2 > &li) const
Circle/Line intersection.
Definition: homog2d.hpp:3434
Here is the call graph for this function:

◆ TEST_CASE() [42/93]

TEST_CASE ( "Circle/Line intersection"  ,
""  [int_CL] 
)
2123 {
2124  Line2d_<NUMTYPE> lid(1,1); // diagonal line going through (0,0)
2125  Line2d_<NUMTYPE> liv; // vertical line at x=0
2126  Line2d_<NUMTYPE> lih( Point2d(-1,0), Point2d(1,0) ); // horizontal line at y=0
2128  {
2129  CHECK( lid.intersects( Point2d_<NUMTYPE>(), 0.5 )() );
2130  auto ri = lid.intersects( Point2d_<NUMTYPE>(), 0.5 );
2131  CHECK( ri() == true );
2132  auto ri2 = lid.intersects( Point2d_<NUMTYPE>(10,5), 1. );
2133  CHECK( ri2() == false );
2134  auto ri3 = lid.intersects( Circle_<NUMTYPE>(Point2d_<NUMTYPE>(), 0.5 ) );
2135  CHECK( ri3() == true );
2136  auto ri4 = lid.intersects( Circle_<NUMTYPE>(Point2d_<NUMTYPE>(10,5), 1. ) );
2137  CHECK( ri4() == false );
2138  }
2139  {
2140  auto rih = lih.intersects( pt, 1.0 );
2141  CHECK( rih() == true );
2142  CHECK( rih.get().first == Point2d(-1,0) );
2143  CHECK( rih.get().second == Point2d(+1,0) );
2144  }
2145  {
2146  auto riv = liv.intersects( pt, 1.0 );
2147  CHECK( riv() == true );
2148  CHECK( riv.get().first == Point2d(0,-1) );
2149  CHECK( riv.get().second == Point2d(0,+1) );
2150  }
2151 
2152  Circle_<NUMTYPE> cir2(45);
2153  CHECK( cir2.radius() == 45. );
2154  Circle_<NUMTYPE> cir3( Point2d(4,6),7);
2155  CHECK( cir3.radius() == 7. );
2156  {
2157  auto cl1 = cir2.intersects( liv );
2158  CHECK( cl1() == true );
2159  CHECK( cl1.get().first == Point2d(0,-45) );
2160  CHECK( cl1.get().second == Point2d(0,+45) );
2161  }
2162  {
2163  Circle_<NUMTYPE> c4( Point2d(1,1),1);
2164  Line2d_<NUMTYPE> l4( Point2d(-5,1), Point2d(5,1));
2165  auto res1 = c4.intersects( l4 );
2166  CHECK( res1() == true );
2167  CHECK( res1.size() == 2 );
2168  CHECK( res1.get().first == Point2d(0,1) );
2169  CHECK( res1.get().second == Point2d(2,1) );
2170 
2171  auto res2 = l4.intersects( c4 );
2172  CHECK( res2() == true );
2173  CHECK( res2.size() == 2 );
2174  CHECK( res2.get().first == Point2d(0,1) );
2175  CHECK( res2.get().second == Point2d(2,1) );
2176  }
2177 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4285
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [43/93]

TEST_CASE ( "Line/Segment intersection"  ,
""  [int_LS] 
)
2181 {
2182  Line2d_<NUMTYPE> li; // vertical line x=0
2183  {
2184  Segment_<NUMTYPE> seg; // (0,0 -- (1,1)
2185  CHECK( li.intersects( seg )() );
2186  CHECK( seg.intersects( li )() );
2187  auto ri1 = li.intersects( seg );
2188  auto ri2 = seg.intersects( li );
2189  CHECK( ri1.size() == 1 );
2190  CHECK( ri2.size() == 1 );
2191 
2192  CHECK( ri1.get() == Point2d(0,0) );
2193  CHECK( ri2.get() == Point2d(0,0) );
2194  }
2195  {
2196  Segment_<NUMTYPE> seg( 0,0, 0,2 ); // vertical x=0
2197  CHECK( !li.intersects( seg )() );
2198  CHECK( !seg.intersects( li )() );
2199  }
2200  {
2201  Segment_<NUMTYPE> seg( 1,0, 1,2 );
2202  CHECK( !li.intersects( seg )() );
2203  CHECK( !seg.intersects( li )() );
2204  }
2205 }
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
detail::Intersect< detail::Inters_1, FPT > intersects(const SegVec< SV2, FPT2 > &) const
Segment/Segment intersection.
Definition: homog2d.hpp:8205
Line2d li
Definition: homog2d_test.cpp:4035
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4285
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [44/93]

TEST_CASE ( "Line/FRect intersection"  ,
""  [int_LF] 
)
2208 {
2209  INFO( "with diagonal line" )
2210  {
2211  Line2d_<NUMTYPE> li(1,1); // diagonal line going through (0,0)
2212  Point2d_<NUMTYPE> pt1, pt2; // 0,0
2213 
2214  pt2.set(1,1);
2215  auto ri = li.intersects( FRect(pt1, pt2) );
2216  CHECK( ri() == true );
2217  CHECK( ri.size() == 2 );
2218  auto pts = ri.get();
2219  CHECK( pts[0] == pt1 );
2220  CHECK( pts[1] == pt2 );
2221 
2222  pt1.set( 5,0 );
2223  pt2.set( 6,1 );
2224  ri = li.intersects( FRect(pt1, pt2) );
2225  CHECK( ri() == false );
2226  }
2227  INFO( "with H/V line" )
2228  {
2229  Point2d_<NUMTYPE> pt1, pt2(1,1); // rectangle (0,0) - (1,1)
2230  FRect_<NUMTYPE> r1(pt1, pt2);
2231  Line2d_<NUMTYPE> li = Point2d_<NUMTYPE>() * Point2d_<NUMTYPE>(0,1); // vertical line at y=x
2232  auto ri1 = li.intersects( r1 );
2233  auto ri2 = r1.intersects( li );
2234  CHECK( ri1() == true );
2235  CHECK( ri2() == true );
2236 
2237  CHECK( ri1.size() == 2 );
2238  CHECK( ri2.size() == 2 );
2239  auto pts1 = ri1.get();
2240  auto pts2 = ri2.get();
2241  CHECK( pts1[0] == pt1 );
2242  CHECK( pts1[1] == Point2d(0,1) );
2243 
2244  CHECK( pts2[0] == pt1 );
2245  CHECK( pts2[1] == Point2d(0,1) );
2246 
2247  li = Point2d_<NUMTYPE>(1,0) * Point2d_<NUMTYPE>(1,1); // vertical line at x=1
2248  ri1 = li.intersects( r1 );
2249  ri2 = r1.intersects( li );
2250  CHECK( ri1() == true );
2251  CHECK( ri2() == true );
2252  CHECK( ri1.size() == 2 );
2253  CHECK( ri2.size() == 2 );
2254 
2255  pts1 = ri1.get();
2256  CHECK( pts1[0] == Point2d(1,0) );
2257  CHECK( pts1[1] == Point2d(1,1) );
2258 
2259  li = Point2d_<NUMTYPE>() * Point2d_<NUMTYPE>(1,0); // horizontal line at y=0
2260  ri1 = li.intersects( r1 );
2261  ri2 = r1.intersects( li );
2262  CHECK( ri1() == true );
2263  CHECK( ri2() == true );
2264  CHECK( ri1.size() == 2 );
2265  CHECK( ri2.size() == 2 );
2266 
2267  pts1 = ri1.get();
2268  CHECK( pts1[0] == pt1 );
2269  CHECK( pts1[1] == Point2d(1,0) );
2270 
2271  li = Point2d_<NUMTYPE>(-1,1) * Point2d_<NUMTYPE>(1,1); // horizontal line at y=1
2272  ri1 = li.intersects( r1 );
2273  ri2 = r1.intersects( li );
2274  CHECK( ri1() == true );
2275  CHECK( ri2() == true );
2276  CHECK( ri1.size() == 2 );
2277  CHECK( ri2.size() == 2 );
2278 
2279  pts1 = ri1.get();
2280  CHECK( pts1[0] == Point2d(0,1) );
2281  CHECK( pts1[1] == Point2d(1,1) );
2282 
2283  li = Point2d_<NUMTYPE>(-1.,.5) * Point2d_<NUMTYPE>(2.,.5); // horizontal line at y=0.5
2284  ri1 = li.intersects( r1 );
2285  ri2 = r1.intersects( li );
2286  CHECK( ri1() == true );
2287  CHECK( ri2() == true );
2288  CHECK( ri1.size() == 2 );
2289  CHECK( ri2.size() == 2 );
2290 
2291  pts1 = ri1.get();
2292  CHECK( pts1[0] == Point2d(0.,.5) );
2293  CHECK( pts1[1] == Point2d(1.,.5) );
2294  }
2295  INFO( "single point intersection" )
2296  {
2297  FRect_<NUMTYPE> r1( 0,0,1,1 );
2298  Line2d_<NUMTYPE> li( -1,+1, +1,-1 );
2299  auto inter = r1.intersects( li );
2300  CHECK( inter.size() == 1 );
2301  auto pts = inter.get();
2302  CHECK( pts[0] == Point2d(0,0) );
2303  }
2304 }
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4285
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [45/93]

TEST_CASE ( "Colinearity"  ,
""  [colinearity] 
)
2312 {
2313  Point2d p00(0,0), p01(0,1), p30(3,0);
2314  Point2d pt1, pt2, pt3;
2315 
2316  {
2317  pt1 = p01; pt2 = p00; pt3 = p30; // case A
2318  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2319  CHECK( arr[0]==pt3 );
2320  CHECK( arr[1]==pt1 );
2321  CHECK( arr[2]==pt2 );
2322  }
2323  {
2324  pt1 = p01; pt2 = p30; pt3 = p00; // case B
2325  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2326  CHECK( arr[0]==pt2 );
2327  CHECK( arr[1]==pt1 );
2328  CHECK( arr[2]==pt3 );
2329  }
2330  {
2331  pt1 = p00; pt2 = p01; pt3 = p30; // case C
2332  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2333  CHECK( arr[0]==pt3 );
2334  CHECK( arr[1]==pt2 );
2335  CHECK( arr[2]==pt1 );
2336  }
2337  {
2338  pt1 = p30; pt2 = p01; pt3 = p00; // case D
2339  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2340  CHECK( arr[0]==pt1 );
2341  CHECK( arr[1]==pt2 );
2342  CHECK( arr[2]==pt3 );
2343  }
2344  {
2345  pt1 = p00; pt2 = p30; pt3 = p01; // case E
2346  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2347  CHECK( arr[0]==pt2 );
2348  CHECK( arr[1]==pt3 );
2349  CHECK( arr[2]==pt1 );
2350  }
2351  {
2352  pt1 = p30; pt2 = p00; pt3 = p01; // case F
2353  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2354  CHECK( arr[0]==pt1 );
2355  CHECK( arr[1]==pt3 );
2356  CHECK( arr[2]==pt2 );
2357  }
2358  {
2359  Point2d p1(0,0), p2(1,0), p3(4,0);
2360  CHECK( areCollinear( p1, p2, p3 ) );
2361  }
2362  {
2363  Point2d p1(1,0), p2(0,0), p3(4,0);
2364  CHECK( areCollinear( p1, p2, p3 ) );
2365  }
2366  {
2367  Point2d p1(1,0), p2(0,0), p3(4,1E-3);
2368  CHECK( !areCollinear( p1, p2, p3 ) );
2369  }
2370 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
std::array< PT, 3 > getLargestDistancePoints(PT pt1, PT pt2, PT pt3)
Helper function, used to check for colinearity of three points.
Definition: homog2d.hpp:3578
bool areCollinear(const Point2d_< FPT > &pt1, const Point2d_< FPT > &pt2, const Point2d_< FPT > &pt3)
Returns true if the 3 points are on the same line.
Definition: homog2d.hpp:3649
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [46/93]

TEST_CASE ( "Line2d"  ,
""  [line1] 
)
2373 {
2375  CHECK( li.area() == 0. );
2376  CHECK_THROWS( li.length() );
2377 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
constexpr HOMOG2D_INUMTYPE area() const
Neither lines nor points have an area.
Definition: homog2d.hpp:4273
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE length() const
A point has a null length, a line has an infinite length.
Definition: homog2d.hpp:4262
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [47/93]

TEST_CASE ( "Circle"  ,
""  [cir1] 
)

?

2380 {
2381  {
2382  Circle_<NUMTYPE> c1; // Default constructor
2383  CHECK( c1.center() == Point2d(0,0) );
2384  CHECK( center(c1) == Point2d(0,0) );
2385  CHECK( c1.radius() == 1. );
2386  CHECK( radius(c1) == 1. );
2387  CHECK( c1.getBB() == FRect(-1,-1,1,1 ) );
2388  CHECK( getBB(c1) == FRect(-1,-1,1,1 ) );
2389 
2390  CHECK( c1.area() == area(c1) );
2391  CHECK( c1.length() == length(c1) );
2392  }
2393  {
2394  int i = 44;
2395  Circle_<NUMTYPE> c1(i); // 1-arg Constructor - radius
2396  CHECK( c1.center() == Point2d(0,0) );
2397  CHECK( c1.radius() == i );
2398  CHECK( c1.getBB() == FRect(-i,-i,i,i) );
2399  CHECK( getBB(c1) == FRect(-i,-i,i,i) );
2400  c1.set( 454 );
2401  CHECK( c1.center() == Point2d(0,0) );
2402  CHECK( c1.radius() == 454 );
2403  }
2404  {
2405  Point2d_<NUMTYPE> pt( 4,5);
2406  Circle_<NUMTYPE> c2(pt); // 1-arg Constructor - center
2407  CHECK( c2.center() == Point2d(4,5) );
2408  CHECK( c2.radius() == 1 );
2409 
2410  CHECK( center(c2) == Point2d(4,5) ); // free functions call
2411  CHECK( radius(c2) == 1 );
2412 
2413  c2.set( Point2d_<NUMTYPE>(18,22) );
2414  CHECK( c2.center() == Point2d(18,22) );
2415  CHECK( c2.radius() == 1 );
2416  }
2417  {
2418  Point2d_<NUMTYPE> pt1(0,0), pt2(4,0);
2419  Circle_<NUMTYPE> c1(pt1,pt2); // 2-args constructor: 2 points
2420  CHECK( c1.center() == Point2d(2,0) );
2421  CHECK( c1.radius() == 2. );
2422  c1.set( Point2d(1,1), Point2d(1,5) );
2423  CHECK( c1.center() == Point2d(1,3) );
2424  CHECK( c1.radius() == 2. );
2425  }
2426  {
2427  Point2d_<NUMTYPE> pt1(4,5);
2428  Circle_<NUMTYPE> c2(pt1,3); // 2-args constructor - center and radius
2429  CHECK( c2.center() == pt1 );
2430  CHECK( c2.radius() == 3 );
2431 
2432  c2.set( Point2d_<NUMTYPE>(42,24), 18 );
2433  CHECK( c2.center() == Point2d_<NUMTYPE>(42,24) );
2434  CHECK( c2.radius() == 18 );
2435  }
2436  {
2437  Circle_<NUMTYPE> c1(1,2,3); // 3-args constructor: x0, y0, radius
2438  CHECK( c1.center() == Point2d(1,2) );
2439  CHECK( c1.radius() == 3 );
2440 
2441  c1.set( 11, 22, 33 );
2442  CHECK( c1.center() == Point2d(11,22) );
2443  CHECK( c1.radius() == 33 );
2444  }
2445  {
2446  CHECK_THROWS( Circle_<NUMTYPE>(1,2,0.) );
2447  CHECK_THROWS( Circle_<NUMTYPE>(1,2,-1.) );
2448  }
2449  {
2450  Point2d_<NUMTYPE> pt1(4,5), pt2(6,7), pt3; // 3-args constructor: 3 points
2451  Circle_<NUMTYPE> c1(pt1,pt2,pt3); // 2-args constructor: 2 points
2452 
2453  c1.set( Point2d(4,5), Point2d(6,7), Point2d(2,2) );
2454 
2455  CHECK_THROWS( c1.set( Point2d(4,5), Point2d(4,5) ) ); // points must be different !
2456  CHECK_THROWS( c1.set( Point2d(4,5), Point2d(4,5), Point2d(2,2) ) );
2457  CHECK_THROWS( Circle( Point2d(4,5), Point2d(4,5), Point2d(2,2) ) );
2458  CHECK_THROWS( Circle( Point2d(4,5), Point2d(4,5) ) );
2459  }
2460  {
2461  Circle_<NUMTYPE> c1;
2462 
2463  CHECK( c1.radius() == 1 );
2464  c1.radius() = 2; // member function call
2465  CHECK( c1.radius() == 2 );
2466  radius(c1) = 3; // free function call
2467  CHECK( radius(c1) == 3 );
2468 
2469  CHECK( center(c1) == Point2d() );
2470  c1.center() = Point2d(3,4); // member function call
2471  CHECK( center(c1) == Point2d(3,4) );
2472  center(c1) = Point2d(5,6); // free function call
2473  CHECK( center(c1) == Point2d(5,6) );
2474  }
2475 }
HOMOG2D_INUMTYPE area() const
Area of circle.
Definition: homog2d.hpp:3269
A circle.
Definition: homog2d.hpp:378
auto getBB() const
Returns Bounding Box of circle.
Definition: homog2d.hpp:3281
Point2d_< FPT > & center(Circle_< FPT > &cir)
Returns reference on center of circle (free function), non-const version.
Definition: homog2d.hpp:10934
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
HOMOG2D_INUMTYPE length(const T &elem)
Returns length of element or variant (free function)
Definition: homog2d.hpp:10223
HOMOG2D_INUMTYPE length() const
Perimeter of circle.
Definition: homog2d.hpp:3275
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
void set(const Point2d_< PT > &center)
Set circle center point, radius unchanged.
Definition: homog2d.hpp:3297
FPT & radius(Circle_< FPT > &cir)
Returns reference on radius of circle (free function), non-const version.
Definition: homog2d.hpp:10916
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10238
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259
Point2d pt
Definition: homog2d_test.cpp:4034
FPT & radius()
Definition: homog2d.hpp:3256
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [48/93]

TEST_CASE ( "Circle from points"  ,
""  [cir2] 
)
2478 {
2479  {
2480  INFO( "circle from 2 pts");
2481  std::vector<Point2d_<NUMTYPE>> pts1{ {0,0}, {2,0} };
2482  std::vector<Point2d_<NUMTYPE>> pts2{ {0,3}, {4,3} };
2483 // check using constructor
2484  Circle_<NUMTYPE> c1(pts1);
2485  CHECK( c1.center() == Point2d(1,0) );
2486  CHECK( c1.radius() == 1. );
2487  Circle_<NUMTYPE> c2(pts2);
2488  CHECK( c2.center() == Point2d(2,3) );
2489  CHECK( c2.radius() == 2. );
2490 // check using "set" function
2491  c1.set(pts2);
2492  CHECK( c1.center() == Point2d(2,3) );
2493  CHECK( c1.radius() == 2. );
2494  c2.set(pts1);
2495  CHECK( c2.center() == Point2d(1,0) );
2496  CHECK( c2.radius() == 1. );
2497  }
2498  {
2499  INFO( "circle from 4 pts");
2500  std::vector<Point2d_<NUMTYPE>> pts1{ {0,4}, {4,0}, {0,-4}, {0,0} };
2501  Circle_<NUMTYPE> c1(pts1);
2502  CHECK( c1.center() == Point2d(0,0) );
2503  CHECK( c1.radius() == 4. );
2504  c1.set(pts1);
2505  CHECK( c1.center() == Point2d(0,0) );
2506  CHECK( c1.radius() == 4. );
2507 
2508  std::vector<Point2d_<NUMTYPE>> pts2{ {0,4} };
2509  CHECK_THROWS( Circle_<NUMTYPE>(pts2) ); // 1 point not allowed
2510  std::vector<Point2d_<NUMTYPE>> pts3;
2511  CHECK_THROWS( Circle_<NUMTYPE>(pts3) ); // 0 points not allowed
2512  }
2513 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
Here is the call graph for this function:

◆ TEST_CASE() [49/93]

TEST_CASE ( "Ellipse"  ,
""  [ell1] 
)
2516 {
2517  {
2518  Ellipse_<NUMTYPE> el;
2519  CHECK( el.getCenter() == Point2d(0,0) );
2520  CHECK( getCenter(el) == Point2d(0,0) );
2521  CHECK( el.getMajMin().first == 2.0 );
2522  CHECK( el.getMajMin().second == 1.0 );
2523  CHECK( el.angle() == 0.0 );
2524  CHECK( angle(el) == 0.0 );
2525  CHECK( el.isCircle() == false );
2526  CHECK( isCircle(el) == false );
2527  // CHECK( el.getBB() == Point2d(0,0) );
2528  }
2529  {
2530  Circle c(1,2,3);
2531  Ellipse_<NUMTYPE> el(c);
2532  CHECK( el.getCenter() == Point2d(1,2) );
2533  CHECK( getCenter(el) == Point2d(1,2) );
2534  CHECK( el.getMajMin().first == 3.0 );
2535  CHECK( el.getMajMin().second == 3.0 );
2536  CHECK( el.angle() == 0.0 );
2537  CHECK( angle(el) == 0.0 );
2538  CHECK( el.isCircle() == true );
2539  CHECK( isCircle(el) == true );
2540  }
2541 
2542  {
2543  Ellipse_<NUMTYPE> el(1,2,3.0,3.00001);
2544  CHECK( el.getCenter() == Point2d(1,2) );
2545  CHECK( el.isCircle() == false ); // using default threshold
2546  CHECK( isCircle(el) == false );
2547 
2548  CHECK( el.isCircle(1E-3) == true ); // using arbitrary threshold
2549  CHECK( isCircle(el,1E-3) == true );
2550  }
2551 
2552  {
2553  Ellipse_<NUMTYPE> el(4,5,6,7);
2554  CHECK( el.getCenter() == Point2d(4,5) );
2555  CHECK( el.getMajMin().first == Approx(7.0) );
2556  CHECK( el.getMajMin().second == Approx(6.0) );
2557  CHECK( el.angle() == 0.0 );
2558  CHECK( el.isCircle() == false );
2559  }
2560  {
2561  Ellipse_<NUMTYPE> el(4,5, 6, 7, 1 /*rad.*/ );
2562  CHECK( el.getCenter() == Point2d(4,5) );
2563  CHECK( el.getMajMin().first == Approx(7.0) );
2564  CHECK( el.getMajMin().second == Approx(6.0) );
2565  CHECK( el.angle() == Approx(1.0) );
2566  CHECK( el.isCircle() == false );
2567  }
2568 }
A circle.
Definition: homog2d.hpp:378
Point2d_< FPT > getCenter() const
Returns center of ellipse.
Definition: homog2d.hpp:8581
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< FPT > getCenter(const Segment_< FPT > &seg)
Free function, returns middle point of segment.
Definition: homog2d.hpp:10705
bool isCircle(const Ellipse_< FPT > &ell, HOMOG2D_INUMTYPE thres=1.E-10)
Returns true if ellipse is a circle.
Definition: homog2d.hpp:11056
std::pair< HOMOG2D_INUMTYPE, HOMOG2D_INUMTYPE > getMajMin() const
Definition: homog2d.hpp:8590
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10993
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
bool isCircle(HOMOG2D_INUMTYPE thres=1.E-10) const
Returns true if ellipse is a circle.
Definition: homog2d.hpp:8564
HOMOG2D_INUMTYPE angle() const
Returns angle of ellipse.
Definition: homog2d.hpp:8601
Here is the call graph for this function:

◆ TEST_CASE() [50/93]

TEST_CASE ( "OSegment point side"  ,
""  [oseg-pt-side] 
)
2580 {
2581  OSegment_<NUMTYPE> s1( 0,0,10,0);
2583  CHECK( s1.getPointSide(pt) == PointSide::Neither );
2584  pt.translate(1,1);
2585  CHECK( s1.getPointSide(pt) == PointSide::Left );
2586  pt.translate(0,-5);
2587  CHECK( s1.getPointSide(pt) == PointSide::Right );
2588 
2589  pt.set(0,0);
2590  s1.set( 1,0, 1,10 );
2591  CHECK( s1.getPointSide(pt) == PointSide::Left );
2592 }
void translate(T1 dx, T2 dy)
Translate Point2d, does nothing for Line2d.
Definition: homog2d.hpp:4142
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [51/93]

TEST_CASE ( "Segment"  ,
""  [seg1] 
)
2595 {
2596  { // test order of points
2597  Point2d p1(43,8);
2598  Point2d p2(43,18);
2599  Point2d p3(5,55);
2600  {
2601  Segment_<NUMTYPE> s( p1, p2 ); // same x value
2602  CHECK( s.getPts().first == p1 );
2603  CHECK( s.getPts().second == p2 );
2604 
2605  s.translate( 2, 3 );
2606  CHECK( s.getPts().first == Point2d(45,11) );
2607  CHECK( s.getPts().second == Point2d(45,21) );
2608 
2609  translate( s, -2, -3 );
2610  CHECK( s.getPts().first == Point2d(43,8) );
2611  CHECK( s.getPts().second == Point2d(43,18) );
2612  }
2613  {
2614  Segment_<NUMTYPE> s( p2, p1 ); // same x value
2615  CHECK( s.getPts().first == p1 );
2616  CHECK( s.getPts().second == p2 );
2617  }
2618  {
2619  Segment_<NUMTYPE> s( p1, p3 );
2620  CHECK( s.getPts().first == p3 );
2621  CHECK( s.getPts().second == p1 );
2622  }
2623  {
2624  Segment_<NUMTYPE> s( p3, p1 );
2625  CHECK( s.getPts().first == p3 );
2626  CHECK( s.getPts().second == p1 );
2627  }
2628  }
2629  {
2630  Point2d_<NUMTYPE> p1( 4,5 );
2631  Point2d_<NUMTYPE> p2( 1,2 );
2632  auto ppts = std::make_pair( p1, p2 );
2633  Segment_<NUMTYPE> s( ppts );
2634  CHECK( s.getPts().first == p2 );
2635  CHECK( s.getPts().second == p1 );
2636  s.set( ppts );
2637  }
2638  {
2639  Line2d_<NUMTYPE> li( Point2d(0,0), Point2d(2,2) );
2640  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2641  Segment_<NUMTYPE> s2( Point2d(2,2), Point2d(0,0) );
2642  CHECK( s1 == s2 );
2643  CHECK( s1.isParallelTo(s2) );
2644  Line2d_<NUMTYPE> l1( Point2d(10,0), Point2d(12,2) );
2645  CHECK( s1.isParallelTo(l1) );
2646  CHECK( l1.isParallelTo(s1) );
2647  CHECK( l1.getAngle( s1 ) == Approx(0) );
2648  CHECK( s1.getAngle( l1 ) == Approx(0) );
2649  CHECK( s1.getAngle( s2 ) == Approx(0) );
2650  CHECK( getAngle( s1, s2 ) == Approx(0) );
2651  CHECK( getAngle( li, s2 ) == Approx(0) );
2652  CHECK( getAngle( s2, li ) == Approx(0) );
2653  }
2654  {
2655  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(3,4) );
2656  CHECK( s1.length() == 5 );
2657  CHECK( s1.area() == 0 );
2658 
2659  Segment_<NUMTYPE> s2( Point2d(9,9), Point2d(8,8) );
2660  auto pts = s2.getPts();
2661  CHECK( pts.first == Point2d_<NUMTYPE>(8,8) );
2662  CHECK( pts.second == Point2d_<NUMTYPE>(9,9) );
2663  }
2664  {
2665  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2666  Segment_<NUMTYPE> s2( Point2d(2,0), Point2d(0,2) );
2667  auto si = s1.intersects(s2);
2668  CHECK( si() == true );
2669  CHECK( si.get() == Point2d_<NUMTYPE>(1,1) );
2670 
2671  auto pt = s1.getCenter();
2672  CHECK( pt == Point2d_<NUMTYPE>(1,1) );
2673  }
2674  {
2675  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2676  Segment_<NUMTYPE> s2( Point2d(2,0), Point2d(0,2) );
2677  auto bis = s1.getBisector();
2678  CHECK( bis == s2.getLine() );
2679  }
2680  { // test that points on a line at equal distance from a point, when
2681  // transformed in a segment, we get back as middle point the same one.
2682  Line2d li(9,9); // diagonal line (0,0) - (9,9)
2683  auto ppts = li.getPoints( GivenCoord::X, 5, 1 );
2684  Segment_<NUMTYPE> s1( ppts.first, ppts.second );
2685  CHECK( s1.getCenter() == Point2d_<NUMTYPE>(5,5) );
2686  }
2687 }
PointPair_< FPT > getPoints(GivenCoord gc, FPT2 coord, FPT3 dist) const
Returns a pair of points that are lying on line at distance dist from a point defined by one of its c...
Definition: homog2d.hpp:4085
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9204
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4035
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
void translate(T &prim, FP1 dx, FP2 dy)
Translate primitive prim (free function)
Definition: homog2d.hpp:11015
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [52/93]

TEST_CASE ( "Translate"  ,
""  [trans] 
)
2690 {
2691  INFO( "Translate Circle" );
2692  Circle_<NUMTYPE> c(5,5,10);
2693  c.translate(-1,+1);
2694  CHECK( c.center() == Point2d(4,6) );
2695  translate( c, +1, -1 );
2696  CHECK( c.center() == Point2d(5,5) );
2697 
2698  translate( c, std::make_pair(2,3) );
2699  CHECK( c.center() == Point2d(7,8) );
2700  c.translate( std::make_pair(-2,-3) );
2701  CHECK( c.center() == Point2d(5,5) );
2702 
2703  INFO( "Translate Point" );
2704  Point2d_<NUMTYPE> pt(4,5);
2705  pt.translate(-1,+1);
2706  CHECK( pt == Point2d(3,6) );
2707  translate(pt,+1,-1);
2708  CHECK( pt == Point2d(4,5) );
2709 
2710  translate( pt, std::make_pair(2,3) );
2711  CHECK( pt == Point2d(6,8) );
2712  pt.translate( std::make_pair(-2,-3) );
2713  CHECK( pt == Point2d(4,5) );
2714 }
A circle.
Definition: homog2d.hpp:378
void translate(T1 dx, T2 dy)
Translate Point2d, does nothing for Line2d.
Definition: homog2d.hpp:4142
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
void translate(T &prim, FP1 dx, FP2 dy)
Translate primitive prim (free function)
Definition: homog2d.hpp:11015
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [53/93]

TEST_CASE ( "MoveTo"  ,
""  [moveto] 
)
2717 {
2718  INFO( "MoveTo Circle" );
2719  Circle_<NUMTYPE> c(5,5,10);
2720  c.moveTo( 9,8 );
2721  CHECK( c.center() == Point2d(9,8) );
2722  moveTo(c,8,9);
2723  CHECK( c.center() == Point2d(8,9) );
2724 
2725  Point2d_<NUMTYPE> pt1(1,1);
2726  moveTo(c,pt1);
2727  CHECK( c.center() == pt1 );
2728  Point2d_<NUMTYPE> pt2(3,3);
2729  c.moveTo(pt2);
2730  CHECK( c.center() == pt2 );
2731 
2732 // INFO( "MoveTo Segment" );
2733 
2734 
2735 }
A circle.
Definition: homog2d.hpp:378
void moveTo(T &prim, const Point2d_< FP > &pt)
Move primitive to other location (free function)
Definition: homog2d.hpp:11037
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [54/93]

TEST_CASE ( "Segment-split-1"  ,
""  [seg-split-1] 
)
2738 {
2739  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(20,0) );
2740  OSegment_<NUMTYPE> s2( Point2d(0,0), Point2d(20,0) );
2741  {
2742  auto psegs1 = s1.split();
2743  auto psegs2 = split(s1);
2744  CHECK( psegs1 == psegs2 );
2745  CHECK( psegs1.first == Segment_<NUMTYPE>( Point2d(0,0), Point2d(10,0) ) );
2746  CHECK( psegs1.second == Segment_<NUMTYPE>( Point2d(10,0), Point2d(20,0) ) );
2747  }
2748  {
2749  auto psegs1 = s2.split();
2750  auto psegs2 = split(s2);
2751  CHECK( psegs1 == psegs2 );
2752  CHECK( psegs1.first == OSegment_<NUMTYPE>( Point2d(0,0), Point2d(10,0) ) );
2753  CHECK( psegs1.second == OSegment_<NUMTYPE>( Point2d(10,0), Point2d(20,0) ) );
2754  }
2755 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
std::pair< base::SegVec< SV, FPT >, base::SegVec< SV, FPT > > split(const base::SegVec< SV, FPT > &seg)
Returns a pair of segments, corresponding to the input segment split by middle point (free function) ...
Definition: homog2d.hpp:10649
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [55/93]

TEST_CASE ( "Segment-split-2"  ,
""  [seg-split-2] 
)
2758 {
2759  OSegment_<NUMTYPE> s1( Point2d(0,0), Point2d(20,0) );
2760 
2761  CHECK_THROWS( s1.split(-4) );
2762  CHECK_THROWS( s1.split(0) );
2763  CHECK_THROWS( s1.split(20) );
2764 
2765  CHECK_THROWS( split(s1,-4) );
2766  CHECK_THROWS( split(s1,0) );
2767  CHECK_THROWS( split(s1,20) );
2768 
2769  auto psegs1 = s1.split(4);
2770  auto psegs2 = split(s1,4);
2771  CHECK( psegs1 == psegs2 );
2772  CHECK( psegs1.first == OSegment_<NUMTYPE>( Point2d(0,0), Point2d(4,0) ) );
2773  CHECK( psegs1.second == OSegment_<NUMTYPE>( Point2d(4,0), Point2d(20,0) ) );
2774 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
std::pair< base::SegVec< SV, FPT >, base::SegVec< SV, FPT > > split(const base::SegVec< SV, FPT > &seg)
Returns a pair of segments, corresponding to the input segment split by middle point (free function) ...
Definition: homog2d.hpp:10649
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [56/93]

TEST_CASE ( "Segment 2"  ,
""  [seg2] 
)
2777 {
2778  {
2779  Segment_<HOMOG2D_INUMTYPE> seg (0,0,1,0); // horizontal segment
2780  auto psegs = seg.getParallelSegs(1.);
2781  auto psegs2 = seg.getParallelSegs(1.);
2782  CHECK( psegs == psegs2 );
2783  CHECK( psegs.first == Segment(0,-1,1,-1) );
2784  CHECK( psegs.second == Segment(0,+1,1,+1) );
2785  }
2786  {
2787  Segment_<HOMOG2D_INUMTYPE> seg (0,0,0,1); // vertical segment
2788  auto psegs = seg.getParallelSegs(1.);
2789  CHECK( psegs.first == Segment(-1,0,-1,+1) );
2790  CHECK( psegs.second == Segment(+1,0,+1,+1) );
2791  }
2792 }
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
std::pair< SegVec, SegVec > getParallelSegs(T dist) const
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [57/93]

TEST_CASE ( "Segment extended"  ,
""  [seg_extended] 
)
2795 {
2797  auto s2 = seg.getExtended();
2798  CHECK( s2.length() == 3. );
2799  CHECK( s2.getPts().first == Point2d(-1,0) );
2800  CHECK( s2.getPts().second == Point2d(2,0) );
2801 
2802  auto s3 = getExtended(seg);
2803  CHECK( s3.length() == 3. );
2804  CHECK( s3.getPts().first == Point2d(-1,0) );
2805  CHECK( s3.getPts().second == Point2d(2,0) );
2806 }
Segment_< FPT > getExtended(const Segment_< FPT > &seg)
Returns Extended Segment (free function)
Definition: homog2d.hpp:10640
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
SegVec< SV, FPT > getExtended() const
Returns a segment with same support line but tripled length.
Definition: homog2d.hpp:5476
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [58/93]

TEST_CASE ( "Segment orthogonal"  ,
""  [seg_orthog] 
)
2809 {
2811  auto pts = seg.getOrthogPts();
2812  auto pts2 = getOrthogPts(seg);
2813  CHECK( pts2 == pts );
2814  auto pol = CPolyline(pts);
2815  CHECK( pol == CPolyline( std::vector<Point2d>{ {0,-1},{1,-1},{1,1},{0,1} } ) );
2816 
2817  auto osegs = seg.getOrthogSegs();
2818  auto osegs2 = getOrthogSegs(seg);
2819  CHECK( osegs2 == osegs );
2820  std::array<Segment_<HOMOG2D_INUMTYPE>,4> gt;
2821  gt[0] = Segment( 0,0,0,+1 );
2822  gt[1] = Segment( 0,0,0,-1 );
2823  gt[2] = Segment( 1,0,1,+1 );
2824  gt[3] = Segment( 1,0,1,-1 );
2825  std::sort( gt.begin(), gt.end() );
2826  std::sort( osegs.begin(), osegs.end() );
2827  CHECK( gt == osegs );
2828 }
Segment seg
Definition: homog2d_test.cpp:4033
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline pol(5, 5u)
std::array< Point2d_< FPT >, 4 > getOrthogPts(const Segment_< FPT > &seg)
Returns the 4 orthogonal points to the segment.
Definition: homog2d.hpp:10679
std::array< Segment_< FPT >, 4 > getOrthogSegs() const
Returns the 4 segments/vectors orthogonal to the segment.
Definition: homog2d.hpp:5239
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12398
std::array< Segment_< FPT >, 4 > getOrthogSegs(const Segment_< FPT > &seg)
Returns the 4 orthogonal segments to the segment.
Definition: homog2d.hpp:10670
std::array< Point2d_< FPT >, 4 > getOrthogPts() const
Returns the 4 points orthogonal to the segment/vector.
Definition: homog2d.hpp:5232
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [59/93]

TEST_CASE ( "min/max of two objects"  ,
""  [minmax] 
)
2831 {
2832  Point2d_<NUMTYPE> pt0(0,0), pt1(1,1), pt2(2,2), pt3(3,3);
2833  auto pp1 = std::make_pair( pt0,pt1 );
2834  auto pp2 = std::make_pair( pt2,pt3 );
2835  auto ppts = getMinMax( pp1, pp2 );
2836  CHECK( ppts.first == Point2d_<NUMTYPE>(0,0) );
2837  CHECK( ppts.second == Point2d_<NUMTYPE>(3,3) );
2838 // TODO: EXTEND
2839 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
auto getMinMax(const PointPair2_< T1, T2 > &pp1, const PointPair2_< T3, T4 > &pp2)
Returns a pair of points holding min and max coordinates of the two input pair of points...
Definition: homog2d.hpp:10398
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [60/93]

TEST_CASE ( "generalized bounding box of two objects"  ,
""  [gen-BB] 
)
2843 {
2844  Point2d_<NUMTYPE> pt,pt2(1,1);
2845  FRect_<NUMTYPE> re,re2;
2846  Segment_<NUMTYPE> se,se2(1,0,0,1);
2847  CPolyline_<NUMTYPE> pc,pc2;
2848  OPolyline_<NUMTYPE> po,po2;
2849  Ellipse_<NUMTYPE> el,el2;
2850 
2851  CHECK( getBB(pt,pt2) == FRect_<NUMTYPE>() ); // (0,0) - (1,1)
2852  CHECK( getBB(se,se2) == FRect_<NUMTYPE>() ); // [(0,0) - (1,1)] - [(1,0) - (0,1)]
2853  CHECK( getBB(se,se) == FRect_<NUMTYPE>() ); // identical segments, but they cover some area
2854  CHECK( getBB(re,re2) == FRect_<NUMTYPE>() );
2855  CHECK( getBB(se,se2) == FRect_<NUMTYPE>() );
2856  CHECK( getBB(el,el2) == getBB(el) ); // identical
2857 
2858  CHECK_THROWS( getBB(pc,pc2) ); // empty
2859  CHECK_THROWS( getBB(pt,pt) ); // identical points => no BB
2860 
2861  pt2.set(0,1);
2862  CHECK_THROWS( getBB(pt,pt2) ); // one of the coordinates is identical
2863 
2864  se.set( 0,0,1,0 );
2865  se2.set( 10,0,11,0 );
2866  CHECK_THROWS( getBB(se,se) ); // segments are colinear
2867  CHECK_THROWS( getBB(se,se2) ); // segments are colinear
2868 
2869  pt2.set(0,0);
2870  CHECK_THROWS( getBB(se,pt2) ); // no area
2871 
2872  pc.set( std::vector<Point2d_<NUMTYPE>>{ {0,0},{1,0} } );
2873  CHECK_THROWS( getBB(pc) ); // no area
2874  CHECK_THROWS( getBB(pc, pc2) ); // no area, and second is empty
2875 
2876  pc2.set( std::vector<Point2d_<NUMTYPE>>{ {5,0},{6,0} } );
2877  CHECK_THROWS( getBB(pc,pc2) ); // colinear
2878 
2879  pc2.set( std::vector<Point2d_<NUMTYPE>>{ {5,1},{6,1} } );
2880  CHECK( getBB(pc,pc2) == FRect_<NUMTYPE>(0,0,6,1) );
2881 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
CHECK_THROWS(CPolyline(-5, 5u))
void set(const Point2d_< FP1 > &p1, const Point2d_< FP2 > &p2)
Setter.
Definition: homog2d.hpp:4960
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [61/93]

TEST_CASE ( "bounding box of container"  ,
""  [BB-cont] 
)
2885 {
2886  {
2887  std::vector<Point2d_<NUMTYPE>> vec(3);
2888  vec[0] = Point2d_<NUMTYPE>(1,1);
2889  vec[1] = Point2d_<NUMTYPE>(5,6);
2890  vec[2] = Point2d_<NUMTYPE>(3,2);
2891  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2892  }
2893  {
2894  std::array<Point2d_<NUMTYPE>,3> vec;
2895  vec[0] = Point2d_<NUMTYPE>(1,1);
2896  vec[1] = Point2d_<NUMTYPE>(5,6);
2897  vec[2] = Point2d_<NUMTYPE>(3,2);
2898  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2899  }
2900  {
2901  std::list<Point2d_<NUMTYPE>> vec;
2902  vec.emplace_back( Point2d_<NUMTYPE>(1,1) );
2903  vec.emplace_back( Point2d_<NUMTYPE>(5,6) );
2904  vec.emplace_back( Point2d_<NUMTYPE>(3,2) );
2905  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2906  }
2907  {
2908  std::vector<Line2d_<NUMTYPE>> vec(3); // cannot get BB of a set of lines
2909  CHECK_THROWS( getBB(vec) );
2910  }
2911  {
2912  std::vector<FRect_<NUMTYPE>> vec(3);
2913  vec[0] = FRect_<NUMTYPE>(1,1,2,2);
2914  vec[1] = FRect_<NUMTYPE>(5,6,10,11);
2915  vec[2] = FRect_<NUMTYPE>(3,2,4,5);
2916  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,10,11) );
2917  }
2918  {
2919  std::vector<Segment_<NUMTYPE>> vec(3);
2920  vec[0] = Segment_<NUMTYPE>(1,1,2,2);
2921  vec[1] = Segment_<NUMTYPE>(5,6,10,11);
2922  vec[2] = Segment_<NUMTYPE>(3,2,4,5);
2923  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,10,11) );
2924  }
2925  {
2926  std::vector<Circle_<NUMTYPE>> vec(3);
2927  vec[0] = Circle_<NUMTYPE>(1,1,1);
2928  vec[1] = Circle_<NUMTYPE>(5,3,2);
2929  vec[2] = Circle_<NUMTYPE>(10,11,2);
2930  CHECK( getBB(vec) == FRect_<NUMTYPE>(0,0,12,13) );
2931  }
2932 #ifdef HOMOG2D_ENABLE_VRTP
2933  {
2934  std::vector<CommonType_<NUMTYPE>> vec(4);
2935  vec[0] = Circle_<NUMTYPE>(3,4,1);
2936  vec[1] = Segment_<NUMTYPE>(5,3,2,8);
2937  vec[2] = FRect_<NUMTYPE>(10,11,2,2);
2938  vec[3] = Line2d_<NUMTYPE>();
2939  CHECK( getBB(vec) == FRect_<NUMTYPE>(10,11,2,2) );
2940  }
2941 #endif
2942 }
A circle.
Definition: homog2d.hpp:378
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CHECK_THROWS(CPolyline(-5, 5u))
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [62/93]

TEST_CASE ( "common bounding box with points "  ,
""  [point2d-BB] 
)
2945 {
2947  FRect_<NUMTYPE> r1;
2948  CHECK( getBB( pt, r1 ) == r1 );
2949  CHECK( getBB( r1, pt ) == r1 );
2950  Segment_<NUMTYPE> seg( 0,0,1,1);
2951  CHECK( getBB( seg, pt ) == r1 );
2952  CHECK( getBB( pt, seg ) == r1 );
2953 
2955  pt.set( 10,0);
2956  CHECK( getBB( pt, cir ) == FRect_<NUMTYPE>(-1.,-1.,+10.,+1. ) );
2957 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3888
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Point2d pt
Definition: homog2d_test.cpp:4034
Circle cir
Definition: homog2d_test.cpp:4036
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [63/93]

TEST_CASE ( "FRect pair bounding box"  ,
""  [frect-BB] 
)
2960 {
2961  { // two identical rectangles
2962  FRect_<NUMTYPE> r1, r2;
2963  CHECK( getBB(r1,r2) == r1 );
2964  }
2965  { // one bottom left, the other top right
2966  FRect_<NUMTYPE> r1(0,0, 1,1);
2967  FRect_<NUMTYPE> r2(2,2, 4,4);
2968  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,4,4) );
2969  }
2970  { // one top left, the other bottom right
2971  FRect_<NUMTYPE> r1(0,2, 1,3);
2972  FRect_<NUMTYPE> r2(2,0, 4,1);
2973  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,4,3) );
2974  }
2975  { // one inside the other
2976  FRect_<NUMTYPE> r1(0,0, 5,5);
2977  FRect_<NUMTYPE> r2(1,1, 3,3);
2978  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,5,5) );
2979  }
2980  { // one inside the other, with a common edge
2981  FRect_<NUMTYPE> r1(0,0, 5,5);
2982  FRect_<NUMTYPE> r2(1,0, 3,3);
2983  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,5,5) );
2984  }
2985 
2986 // test for rectangle of different types
2987  { // one inside the other, with a common edge
2988  FRect_<float> r1(0,0, 5,5);
2989  FRect_<double> r2(1,0, 3,3);
2990  auto bb = getBB(r1,r2);
2991  CHECK( bb == FRect_<long double>(0,0,5,5) );
2992  CHECK( bb.dtype() == Dtype::Float );
2993  }
2994 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Here is the call graph for this function:

◆ TEST_CASE() [64/93]

TEST_CASE ( "bounding box of two objects"  ,
""  [getBB-pair] 
)
2997 {
2998  FRect_<NUMTYPE> r1(0,3, 2,0);
2999  FRect_<NUMTYPE> r2(4,5, 6,8);
3000  FRect_<NUMTYPE> bbr(0,0, 6,8);
3001  CHECK( bbr == getBB( r1,r2 ) );
3002  { // distant segments
3003  Segment_<NUMTYPE> s1(0,3, 2,0);
3004  Segment_<NUMTYPE> s2(4,5, 6,8);
3005  FRect_<NUMTYPE> bbs(0,0, 6,8);
3006  CHECK( bbs == getBB( s1,s2 ) );
3007  }
3008  { // crossing segments
3009  Segment_<NUMTYPE> s1(0,0, 5,5);
3010  Segment_<NUMTYPE> s2(0,6, 4,0);
3011  FRect_<NUMTYPE> bbs(0,0, 5,6);
3012  CHECK( bbs == getBB( s1,s2 ) );
3013  }
3014 
3015  { // one circle inside the other
3016  Circle_<NUMTYPE> c1(0,0, 2);
3017  Circle_<NUMTYPE> c2(0,1, 4);
3018  FRect_<NUMTYPE> bbc(-4,-3, +4,5);
3019  CHECK( bbc == getBB( c1,c2 ) );
3020  }
3021  { // two distant circles
3022  Circle_<NUMTYPE> c1(5,5, 2);
3023  Circle_<NUMTYPE> c2(0,0, 1);
3024  FRect_<NUMTYPE> bbc(-1,-1, 7,7);
3025  CHECK( bbc == getBB( c1,c2 ) );
3026  }
3027  { // CPolyline / Frect
3028  CPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3030  CHECK( getBB(po,rect) == FRect_<NUMTYPE>(0,0,3,2) );
3031  }
3032  { // OPolyline / Frect
3033  OPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3035  CHECK( getBB(po,rect) == FRect_<NUMTYPE>(0,0,3,2) );
3036  }
3037  { // OPolyline / Segment
3038  OPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3039  Segment_<NUMTYPE> seg; // [0,0]-[1,1]
3040  CHECK( getBB(seg,po) == FRect_<NUMTYPE>(0,0,3,2) );
3041  }
3042  { // 2 CPolyline, one is empty
3043  CPolyline_<NUMTYPE> po1( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3044  CPolyline_<NUMTYPE> po2;
3045  CHECK( getBB(po1,po2) == getBB(po1) );
3046  }
3047  { // Circle / Frect
3048  Circle_<NUMTYPE> cir( 5,5,3 ); // center at 5,5, radius=3
3049  FRect_<NUMTYPE> rect; // (0,0)--(1,1)
3050  CHECK( getBB(cir,rect) == FRect_<NUMTYPE>(0,0,8,8) );
3051  }
3052  { // Circle / Segment
3053  Circle_<NUMTYPE> cir( 5,5,3 ); // center at 5,5, radius=3
3054  Segment_<NUMTYPE> seg(10,20,30,40);
3055  CHECK( getBB(cir,seg) == FRect_<NUMTYPE>(2,2,30,40) );
3056  }
3057  { // Circle / Circle (one inside the other)
3058  Circle_<NUMTYPE> cir1( 5,5,3 ); // center at 5,5, radius=3
3059  Circle_<NUMTYPE> cir2( 5,5,1 ); // center at 5,5, radius=1
3060  CHECK( getBB(cir1,cir2) == FRect_<NUMTYPE>(2,2,8,8) );
3061  }
3062  { // two identical Circles
3063  Circle_<NUMTYPE> cir1,cir2;
3064  CHECK( getBB(cir1,cir2) == FRect_<NUMTYPE>(-1,-1,1,1) );
3065  }
3066  { // two identical Ellipses
3067  Ellipse_<NUMTYPE> e1,e2;
3068  CHECK( getBB(e1,e2) == FRect_<NUMTYPE>(-2,-1,2,1) );
3069  }
3070 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4033
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
FRect rect
Definition: homog2d_test.cpp:4038
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Circle cir
Definition: homog2d_test.cpp:4036
Here is the call graph for this function:

◆ TEST_CASE() [65/93]

TEST_CASE ( "FRect"  ,
""  [frect] 
)
3073 {
3074  {
3075  FRect_<NUMTYPE> r1;
3076  CHECK( r1.width() == 1. );
3077  CHECK( r1.height() == 1. );
3078  CHECK( r1.length() == 4 );
3079  CHECK( r1.area() == 1 );
3080  CHECK( r1.getCenter() == Point2d(0.5,0.5) );
3081 
3082 // free functions
3083  CHECK( width(r1) == 1. );
3084  CHECK( height(r1) == 1. );
3085  CHECK( length(r1) == 4 );
3086  CHECK( area(r1) == 1 );
3087  CHECK( getCenter(r1) == Point2d(0.5,0.5) );
3088 
3089  auto p_pts = r1.getPts();
3090  CHECK( p_pts.first == Point2d() );
3091  CHECK( p_pts.second == Point2d(1.,1.) );
3092 
3093  auto pts = r1.get4Pts();
3094  CHECK( pts[0] == Point2d(0,0) );
3095  CHECK( pts[1] == Point2d(0,1) );
3096  CHECK( pts[2] == Point2d(1,1) );
3097  CHECK( pts[3] == Point2d(1,0) );
3098  }
3099  CHECK_THROWS( FRect_<NUMTYPE>( Point2d(4,5), Point2d(4,2) ) );
3100  {
3101  FRect_<NUMTYPE> r2a( Point2d(6,5), Point2d(1,2) );
3102  FRect_<NUMTYPE> r2b( Point2d(6,2), Point2d(1,5) );
3103  CHECK( r2a == r2b );
3104 
3105  CHECK( r2a.width() == 5. );
3106  CHECK( r2a.height() == 3. );
3107  auto p_pts = r2b.getPts();
3108  CHECK( p_pts.first == Point2d(1,2) );
3109  CHECK( p_pts.second == Point2d(6,5) );
3110 
3111  auto pts = r2b.get4Pts();
3112  CHECK( pts[0] == Point2d(1,2) );
3113  CHECK( pts[1] == Point2d(1,5) );
3114  CHECK( pts[2] == Point2d(6,5) );
3115  CHECK( pts[3] == Point2d(6,2) );
3116  }
3117  {
3118  FRect_<NUMTYPE> r;
3119  auto s = r.getSegs();
3120  auto s2 = getSegs( r );
3121  CHECK( s == s2 );
3122  CHECK( s[0] == Segment(0,0, 0,1) );
3123  CHECK( s[1] == Segment(0,1, 1,1) );
3124  CHECK( s[2] == Segment(1,1, 1,0) );
3125  CHECK( s[3] == Segment(1,0, 0,0) );
3126  }
3127  {
3128  FRect_<NUMTYPE> r( Point2d(0,0), 100, 50 );
3129  CHECK( r.width() == 100 );
3130  CHECK( r.height() == 50 );
3131  CHECK( r.length() == 300 );
3132  CHECK( r.area() == 5000 );
3133  CHECK( r.getCenter() == Point2d(0,0) );
3134  }
3135  {
3136  FRect_<NUMTYPE> r1( 0,0, 5, 3 );
3137  FRect_<NUMTYPE> r2( 2,3, 7, 6 );
3138  CHECK( r1.size() == r2.size() );
3139  CHECK( size(r1) == size(r2) );
3140  }
3141 }
Point2d_< FPT > getCenter() const
Returns center of rectangle.
Definition: homog2d.hpp:2773
HOMOG2D_INUMTYPE height(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10874
std::array< Point2d_< FPT >, 4 > get4Pts() const
Returns the 4 points of the rectangle, starting from "smallest" one, and in clockwise order...
Definition: homog2d.hpp:2910
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
HOMOG2D_INUMTYPE width(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10882
HOMOG2D_INUMTYPE length(const T &elem)
Returns length of element or variant (free function)
Definition: homog2d.hpp:10223
HOMOG2D_INUMTYPE area() const
Definition: homog2d.hpp:2747
Point2d_< FPT > getCenter(const Segment_< FPT > &seg)
Free function, returns middle point of segment.
Definition: homog2d.hpp:10705
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE length() const
Definition: homog2d.hpp:2748
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10253
constexpr size_t size() const
Definition: homog2d.hpp:2750
std::vector< Segment_< FPT > > getSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the segments of the polyline (free function)
Definition: homog2d.hpp:9937
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
std::array< Segment_< FPT >, 4 > getSegs() const
Returns the 4 segments of the rectangle, starting with the first vertical one.
Definition: homog2d.hpp:2934
HOMOG2D_INUMTYPE width() const
Definition: homog2d.hpp:2746
HOMOG2D_INUMTYPE height() const
Definition: homog2d.hpp:2745
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10238
PointPair_< FPT > getPts() const
Returns the 2 major points of the rectangle.
Definition: homog2d.hpp:2767
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [66/93]

TEST_CASE ( "FRect extended"  ,
""  [frect-ext] 
)
3144 {
3146  auto r1a = rect.getExtended();
3147  auto r1b = getExtended(rect);
3148  CHECK( r1a == r1b );
3149  CHECK( r1a == FRect(-1,-1,2,2 ) );
3150  CHECK( r1a.area() == 9 * rect.area() );
3151 
3152  FRect_<NUMTYPE> rect2(4,5,6,6);
3153  CHECK( rect2.getExtended() == FRect(2,4,8,7) );
3154 }
Segment_< FPT > getExtended(const Segment_< FPT > &seg)
Returns Extended Segment (free function)
Definition: homog2d.hpp:10640
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
FRect_< FPT > getExtended() const
Definition: homog2d.hpp:2852
FRect rect
Definition: homog2d_test.cpp:4038
HOMOG2D_INUMTYPE area() const
Definition: homog2d.hpp:2747
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
Here is the call graph for this function:

◆ TEST_CASE() [67/93]

TEST_CASE ( "FRect diagonals"  ,
""  [frect-diags] 
)
3157 {
3158  FRect_<NUMTYPE> r1;
3159  auto psegs1 = r1.getDiagonals();
3160  auto psegs2 = getDiagonals(r1);
3161  CHECK( psegs1 == psegs2 );
3162 
3163  CHECK( psegs1.first == Segment(0,0,1,1) );
3164  CHECK( psegs1.second == Segment(0,1,1,0) );
3165 }
std::pair< Segment_< FPT >, Segment_< FPT > > getDiagonals(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10898
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
std::pair< Segment_< FPT >, Segment_< FPT > > getDiagonals() const
Definition: homog2d.hpp:2864
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Here is the call graph for this function:

◆ TEST_CASE() [68/93]

TEST_CASE ( "Polyline comparison 1"  ,
""  [polyline-comparison-1] 
)
3168 {
3169  std::vector<Point2d_<NUMTYPE>> vpt1{ {0,0}, {1,0}, {1,1} };
3170  std::vector<Point2d_<NUMTYPE>> vpt2{ {1,0}, {1,1}, {0,0} };
3171  {
3172  OPolyline opl1, opl2;
3173  opl1.set( vpt1 );
3174  opl2.set( vpt2 );
3175  CHECK( opl1 != opl2 );
3176 
3177  CPolyline cpl1, cpl2;
3178  cpl1.set( vpt1 );
3179  cpl2.set( vpt2 );
3180  CHECK( cpl1 == cpl2 );
3181 
3182  CHECK( opl1 != cpl1 ); // comparing polygons of different types is allowed
3183  CHECK( opl2 != cpl1 ); // (but will always return false)
3184  }
3185 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [69/93]

TEST_CASE ( "Polyline minimization"  ,
""  [polyline-min] 
)
3189 {
3190  INFO( "Polyline pl2( IsClosed::No" );
3191  {
3192 #include "figures_test/polyline_min_1O.code" // open
3193 
3194  CHECK( pl.size() == 3 );
3195  CHECK( pl.nbSegs() == 2 );
3196  pl.minimize();
3197  CHECK( pl.size() == 2 );
3198  CHECK( pl.nbSegs() == 1 );
3199  }
3200  {
3201 #include "figures_test/polyline_min_1C.code" // closed
3202  CHECK( pl.size() == 3 );
3203  CHECK( pl.nbSegs() == 3 );
3204  pl.minimize();
3205  CHECK( pl.size() == 2 );
3206  CHECK( pl.nbSegs() == 2 );
3207  }
3208  {
3209 #include "figures_test/polyline_min_2O.code"// open
3210  CHECK( pl.size() == 3 );
3211  CHECK( pl.nbSegs() == 2 );
3212  pl.minimize();
3213 // std::cout << "pl:" << pl << '\n';
3214  CHECK( pl.size() == 3 ); // no change
3215  CHECK( pl.nbSegs() == 2 );
3216  }
3217  {
3218 #include "figures_test/polyline_min_2C.code" // closed
3219  CHECK( pl.size() == 3 );
3220  CHECK( pl.nbSegs() == 3 );
3221  pl.minimize();
3222  CHECK( pl.size() == 3 ); // no change !
3223  CHECK( pl.nbSegs() == 3 );
3224  }
3225  {
3226 #include "figures_test/polyline_min_3O.code" // open
3227  CHECK( pl.size() == 4 );
3228  CHECK( pl.nbSegs() == 3 );
3229  pl.minimize();
3230 // std::cout << "pl:" << pl << '\n';
3231  CHECK( pl.size() == 4 ); // no change
3232  CHECK( pl.nbSegs() == 3 );
3233  }
3234  {
3235 #include "figures_test/polyline_min_3C.code" // closed
3236  CHECK( pl.size() == 4 );
3237  CHECK( pl.nbSegs() == 4 );
3238  pl.minimize();
3239 // std::cout << "pl:" << pl << '\n';
3240  CHECK( pl.size() == 3 ); // no change
3241  CHECK( pl.nbSegs() == 3 );
3242  }
3243 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Here is the call graph for this function:

◆ TEST_CASE() [70/93]

TEST_CASE ( "Polyline"  ,
""  [polyline] 
)
3268 {
3269  { // default constructor
3270  OPolyline_<NUMTYPE> pl1;
3271  polytest_1( pl1 );
3272  CPolyline_<NUMTYPE> pl2;
3273  polytest_1( pl2 );
3274  }
3275  {
3276  CPolyline_<NUMTYPE> pc1;
3277  OPolyline_<NUMTYPE> po1;
3278  std::vector<Point2d> vpt{ {0,0} };
3279  CHECK_THROWS( pc1.set( vpt ) ); // can't hold only 1 point
3280  CHECK_THROWS( po1.set( vpt ) );
3281  }
3282  {
3283  std::vector<Point2d> vpt{ {0,0} };
3284  CHECK_THROWS( CPolyline_<NUMTYPE>( vpt ) ); // can(t build a polyline with a vector of size=1
3286  }
3287  { // build from Rectangle
3288  FRect r( 5,6, 7,8 );
3289  CPolyline_<NUMTYPE> pl1( r );
3290 
3291  CHECK( pl1.isSimple() == true );
3292  CHECK( isSimple(pl1) == true );
3293  CHECK( pl1.size() == 4 );
3294  CHECK( size(pl1) == 4 );
3295  CHECK( pl1.nbSegs() == 4 );
3296  CHECK( nbSegs(pl1) == 4 );
3297  CHECK( pl1.length() == 8 );
3298  CHECK( length(pl1) == 8 );
3299  CHECK( pl1.area() == 4 );
3300  CHECK( area(pl1) == 4 );
3301  CHECK( pl1.centroid() == Point2d(6,7) );
3302  CHECK( centroid(pl1) == Point2d(6,7) );
3303 
3304  auto vpts = pl1.getPts();
3305  CHECK( vpts.size() == 4 );
3306  CHECK( vpts[0] == Point2d(5,6) );
3307 
3308  pl1.translate(1,2);
3309  CHECK( pl1 == CPolyline_<NUMTYPE>( FRect( 6,8, 8,10 ) ) );
3310  }
3311  { // set from Rectangle
3312  FRect r( 5,6, 7,8 );
3313  CPolyline_<NUMTYPE> pl1;
3314  pl1.set(r);
3315 
3316  CHECK( pl1.isSimple() == true );
3317  CHECK( pl1.size() == 4 );
3318  CHECK( pl1.getPoint(0) == Point2d(5,6) );
3319  }
3320  {
3321  OPolyline_<NUMTYPE> po1;
3322  CPolyline_<NUMTYPE> pc1;
3323  std::vector<Point2d> vpt{ {0,0},{2,2}, {2,2}, {4,3} };
3324 
3325  CHECK_THROWS( po1.set( vpt ) ); // cant have two contiguous identical points
3326  CHECK_THROWS( pc1.set( vpt ) ); // cant have two contiguous identical points
3327  }
3328  {
3329  std::vector<Point2d> vpt{ {0,0}, {1,1.5}, {3,5}, {1,4} };
3330 
3331  OPolyline_<NUMTYPE> po1(vpt);
3332  CPolyline_<NUMTYPE> pc1(vpt);
3333 
3334  CHECK( po1.isClosed() == false );
3335  CHECK( pc1.isClosed() == true );
3336 
3337  CHECK( po1.size() == 4 );
3338  CHECK( pc1.size() == 4 );
3339 
3340  CHECK( po1.nbSegs() == 3 );
3341  CHECK( pc1.nbSegs() == 4 );
3342 
3343  CHECK( po1.isSimple() == false );
3344  CHECK( pc1.isSimple() == true );
3345 
3346  CPolyline_<NUMTYPE> pc2(po1);
3347  CHECK( pc2.nbSegs() == 4 );
3348  CHECK( pc2.isSimple() == true );
3349 
3350  FRect bb1( 0,0, 3,5);
3351  CHECK( getBB(po1) == bb1 );
3352  CHECK( getBB(pc1) == bb1 );
3353  CHECK( po1.getBB() == bb1 );
3354  CHECK( pc1.getBB() == bb1 );
3355  }
3356  {
3357  std::vector<Point2d> vpt{ {0,0}, {1,1}, {0,1}, {1,0} };
3358  CPolyline_<NUMTYPE> pc1(vpt);
3359  CHECK( pc1.isClosed() == true );
3360  CHECK( pc1.size() == 4 );
3361  CHECK( pc1.nbSegs() == 4 );
3362  CHECK( pc1.isSimple() == false ); // crossing segments
3363 
3364  pc1.translate(2,1.);
3365  CHECK( pc1.getPoint(0) == Point2d(2,1.) ); // (0,0) translated to (2,1)
3366  }
3367  { // build from std::array
3368  std::array<Point2d,3> pts{{ {0,0}, {1,1}, {0,1} }};
3369  CPolyline_<NUMTYPE> pc(pts);
3370  OPolyline_<NUMTYPE> po(pts);
3371  CHECK( pc.isClosed() == true );
3372  CHECK( po.isClosed() == false );
3373  CHECK( pc.size() == 3 );
3374  CHECK( po.size() == 3 );
3375  CHECK( pc.nbSegs() == 3 );
3376  CHECK( po.nbSegs() == 2 );
3377  }
3378  { // build from std::list
3379  std::list<Point2d> pts{ {0,0}, {1,1}, {0,1} };
3380  CPolyline_<NUMTYPE> pc(pts);
3381  OPolyline_<NUMTYPE> po(pts);
3382  CHECK( pc.isClosed() == true );
3383  CHECK( po.isClosed() == false );
3384  CHECK( pc.size() == 3 );
3385  CHECK( po.size() == 3 );
3386  CHECK( pc.nbSegs() == 3 );
3387  CHECK( po.nbSegs() == 2 );
3388  }
3389  { // build from segment
3391  CPolyline_<NUMTYPE> pc( seg );
3392  OPolyline_<NUMTYPE> po( seg );
3393  CHECK( pc.size() == 2 );
3394  CHECK( po.size() == 2 );
3395  CHECK( pc.getPoint(0) == Point2d(0,0) );
3396  CHECK( po.getPoint(0) == Point2d(0,0) );
3397  CHECK( pc.nbSegs() == 2 );
3398  CHECK( po.nbSegs() == 1 );
3399  }
3400  { // build from segment - 2
3401  Segment_<NUMTYPE> seg; // (0,0) - (1,1)
3402  CPolyline_<NUMTYPE> pc1( seg );
3403  OPolyline_<NUMTYPE> po1( seg );
3404  std::list<Point2d> pts{ {1,1},{0,0} };
3405  CPolyline_<NUMTYPE> pc2(pts);
3406  OPolyline_<NUMTYPE> po2(pts);
3407  CHECK( pc1 == pc2 );
3408  CHECK( po1 == po2 );
3409  }
3410 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6245
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6320
void polytest_1(const base::PolylineBase< T, U > &pl1)
Definition: homog2d_test.cpp:3246
Segment seg
Definition: homog2d_test.cpp:4033
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7381
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
HOMOG2D_INUMTYPE length(const T &elem)
Returns length of element or variant (free function)
Definition: homog2d.hpp:10223
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6411
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
base::LPBase< typ::IsPoint, FPT > centroid(const base::PolylineBase< PLT, FPT > &pl)
Returns centroid of Polyline (free function)
Definition: homog2d.hpp:10907
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10253
constexpr bool isClosed() const
Definition: homog2d.hpp:6213
auto getBB() const
Returns Bounding Box of Polyline.
Definition: homog2d.hpp:6226
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10238
size_t nbSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the number of segments (free function)
Definition: homog2d.hpp:9927
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6211
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
bool isSimple(const base::PolylineBase< PLT, FPT > &pl)
Returns true if is a polygon (free function)  
Definition: homog2d.hpp:9907
Here is the call graph for this function:

◆ TEST_CASE() [71/93]

TEST_CASE ( "Polyline setParallelogram"  ,
""  [polyline-setParallelogram] 
)
3433 {
3434  {
3435  Point2d_<NUMTYPE> pt1(0,0);
3436  Point2d_<NUMTYPE> pt2(0,2);
3437  Point2d_<NUMTYPE> pt3(4,5);
3439  pol.setParallelogram( pt1, pt2, pt3 );
3440 
3441  std::vector<Point2d_<NUMTYPE>> vpts{ {0,0}, {0,2}, {4,5}, {4,3} };
3442  CPolyline_<NUMTYPE> pol2(vpts);
3443  CHECK( pol == pol2 );
3444  }
3445 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline pol(5, 5u)
void setParallelogram(const Point2d_< FPT1 > &pt1, const Point2d_< FPT2 > &pt2, const Point2d_< FPT3 > &pt3)
Build a parallelogram (4 points) from 3 points.
Definition: homog2d.hpp:6765
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [72/93]

TEST_CASE ( "Polyline get extreme point"  ,
""  [polyline-getExtremePoint] 
)
3448 {
3449  {
3450  CPolyline cp_empty;
3451  CHECK_THROWS( cp_empty.getLmPoint() );
3452  }
3453  {
3454  Point2d_<NUMTYPE> pt( 3, 4 );
3455  std::vector<Point2d_<NUMTYPE>> vpt{ pt };
3456 
3457  CHECK( getLmPoint(vpt).first == pt );
3458  CHECK( getRmPoint(vpt).first == pt );
3459  CHECK( getTmPoint(vpt).first == pt );
3460  CHECK( getBmPoint(vpt).first == pt );
3461  CHECK( getExtremePoint(CardDir::Left,vpt).first == pt );
3462  }
3463  {
3464  std::vector<Point2d_<NUMTYPE>> vpt{ {1,0}, {0,1}, {-1,0}, {0,-1} };
3465  CPolyline cp( vpt );
3466  CHECK( cp.size() == 4 );
3467  CHECK( cp.getLmPoint() == Point2d_<NUMTYPE>(-1,0) );
3468  CHECK( cp.getRmPoint() == Point2d_<NUMTYPE>(1,0) );
3469  CHECK( cp.getTmPoint() == Point2d_<NUMTYPE>(0,1) );
3470  CHECK( cp.getBmPoint() == Point2d_<NUMTYPE>(0,-1) );
3471 
3472  CHECK( getLmPoint(vpt).first == Point2d_<NUMTYPE>(-1,0) );
3473  CHECK( getRmPoint(vpt).first == Point2d_<NUMTYPE>(1,0) );
3474  CHECK( getTmPoint(vpt).first == Point2d_<NUMTYPE>(0,1) );
3475  CHECK( getBmPoint(vpt).first == Point2d_<NUMTYPE>(0,-1) );
3476  }
3477  {
3478  std::vector<Point2d_<NUMTYPE>> vpt{ {0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {1,2}, {0,2}, {0,1} };
3479  CPolyline cp( vpt );
3480  CHECK( cp.size() == 8 );
3481  CHECK( cp.getLmPoint() == Point2d_<NUMTYPE>(0,0) );
3482  CHECK( cp.getRmPoint() == Point2d_<NUMTYPE>(2,0) );
3483  CHECK( cp.getTmPoint() == Point2d_<NUMTYPE>(0,2) );
3484  CHECK( cp.getBmPoint() == Point2d_<NUMTYPE>(0,0) );
3485 
3486  CHECK( getLmPoint(vpt).first == Point2d_<NUMTYPE>(0,0) );
3487  CHECK( getRmPoint(vpt).first == Point2d_<NUMTYPE>(2,0) );
3488  CHECK( getTmPoint(vpt).first == Point2d_<NUMTYPE>(0,2) );
3489  CHECK( getBmPoint(vpt).first == Point2d_<NUMTYPE>(0,0) );
3490  }
3491 }
auto getExtremePoint(CardDir dir, const T &t)
Get Top-most / Bottom-most / Left-most / Right-most point, depending on dir (free function) ...
Definition: homog2d.hpp:7095
auto getBmPoint(const T &t)
Return Bottom-most point of container holding points.
Definition: homog2d.hpp:6915
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
auto getTmPoint(const T &t)
Return Top-most point of container.
Definition: homog2d.hpp:6940
CHECK_THROWS(CPolyline(-5, 5u))
auto getLmPoint(const T &t)
Return Left-most point of container as a pair holding:
Definition: homog2d.hpp:6987
auto getRmPoint(const T &t)
Return Right-most point of container holding points.
Definition: homog2d.hpp:7028
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d_< FPT > getLmPoint() const
Return Left-most point of Polyline.
Definition: homog2d.hpp:7137
Point2d pt
Definition: homog2d_test.cpp:4034
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [73/93]

TEST_CASE ( "Bounding Box of set of objects"  ,
""  [BB-cont] 
)
3494 {
3495  std::vector<Point2d> vpts1{ {0,0}, {1,1.5}, {3,5}, {1,4} };
3496  FRect bb1( 0,0, 3,5 );
3497  {
3498  CHECK( getBB(vpts1) == bb1 );
3499 
3500  CPolyline cpol( vpts1 );
3501  OPolyline opol( vpts1 );
3502  std::vector<CPolyline> vec_c{ cpol };
3503  std::vector<OPolyline> vec_o{ opol };
3504  CHECK( getBB(vec_c) == bb1 );
3505  CHECK( getBB(vec_o) == bb1 );
3506  }
3507  {
3508  std::vector<Segment> vseg;
3509  CHECK_THROWS( getBB(vseg) );
3510  vseg.emplace_back( Segment(0,0,0,1) );
3511  CHECK_THROWS( getBB(vseg) ); // no area !
3512 
3513  vseg.emplace_back( Segment(4,5,6,7) );
3514  FRect bb2( 0,0, 6,7 );
3515  CHECK( getBB(vseg) == bb2 );
3516  }
3517  {
3518  std::list<Circle> vcir;
3519  CHECK_THROWS( getBB(vcir) ); // empty !
3520  vcir.emplace_back( Circle(1,1,1) );
3521  FRect bb3( 0,0, 2,2 );
3522  CHECK( getBB(vcir) == bb3 );
3523  }
3524  {
3525  std::vector<Point2d> vpt{ {0,11} };
3526  CHECK_THROWS( getBB(vpt) ); // need at least 2 points !
3527 
3528  std::list<Point2d> lpt{ {2,11} };
3529  CHECK_THROWS( getBB(lpt) ); // need at least 2 points !
3530 
3531  std::array<Point2d,1> apt;
3532  apt[0] = Point2d{2,11};
3533  CHECK_THROWS( getBB(apt) ); // need at least 2 points !
3534  }
3535 }
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CHECK_THROWS(CPolyline(-5, 5u))
CPolyline cpol
Definition: homog2d_test.cpp:4030
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10312
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [74/93]

TEST_CASE ( "getCenters() and getLines()"  ,
""  [getCenters] 
)
3538 {
3539  {
3540  std::vector<Segment> vec;
3541  auto out1 = getCenters( vec );
3542  CHECK( out1.empty() );
3543 
3544  vec.emplace_back( Segment( 0,0,2,0) );
3545  vec.emplace_back( Segment( 0,1,2,1) );
3546  auto out2 = getCenters( vec );
3547  CHECK( out2.size() == 2 );
3548  CHECK( out2[0] == Point2d(1,0) );
3549  CHECK( out2[1] == Point2d(1,1) );
3550 
3551  auto out3 = getLines( vec );
3552  CHECK( out3.size() == 2 );
3553  CHECK( out3[0] == Line2d( Point2d(0,0), Point2d(5,0) ) );
3554  CHECK( out3[1] == Line2d( Point2d(0,1), Point2d(5,1) ) );
3555  }
3556  {
3557  std::list<Circle> vec;
3558  auto out1 = getCenters( vec );
3559  CHECK( out1.empty() );
3560 
3561  vec.emplace_back( Circle( 0,0, 2) );
3562  vec.emplace_back( Circle( 1,1, 3) );
3563  auto out2 = getCenters( vec );
3564  CHECK( out2.size() == 2 );
3565  CHECK( out2[0] == Point2d(0,0) );
3566  CHECK( out2[1] == Point2d(1,1) );
3567  }
3568  {
3569  std::array<Ellipse,2> vec;
3570  auto out1 = getCenters( vec );
3571  CHECK( out1.size() == 2 ); // because input array has size=2
3572 
3573  vec[0] = Ellipse( 0,0, 2, 3 );
3574  vec[1] = Ellipse( 1,1, 3, 8 );
3575  auto out2 = getCenters( vec );
3576  CHECK( out2.size() == 2 );
3577  CHECK( out2[0] == Point2d(0,0) );
3578  CHECK( out2[1] == Point2d(1,1) );
3579  }
3580 }
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12376
auto getCenters(const T &vsegs)
Free function, returns middle points of set of segments/circles.
Definition: homog2d.hpp:10743
Ellipse_< HOMOG2D_INUMTYPE > Ellipse
Default ellipse type.
Definition: homog2d.hpp:12402
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
auto getLines(const T &vsegs)
Free function, returns a set of lines from a set of segments.
Definition: homog2d.hpp:10765
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Here is the call graph for this function:

◆ TEST_CASE() [75/93]

TEST_CASE ( "Polygon convexity"  ,
""  [polyline-convex] 
)
3583 {
3584  OPolyline_<NUMTYPE> plo;
3585  CPolyline_<NUMTYPE> plc;
3586  CHECK( !plo.isConvex() ); // empty !!
3587  CHECK( !plc.isConvex() );
3588 
3589  CHECK( !isConvex(plc) ); // free function call
3590  CHECK( !isConvex(plo) );
3591 
3592  plo.set( std::vector<Point2d>{ {0,0}, {2,0} } );
3593  plc.set( std::vector<Point2d>{ {0,0}, {2,0} } );
3594  CHECK( !plo.isConvex() ); // 2 pts are fine, but not convex
3595  CHECK( !plc.isConvex() );
3596 
3597  plo.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1} } );
3598  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1} } );
3599  CHECK( !plo.isConvex() ); // 3 pts ok, but open Polyline never convex
3600  CHECK( plc.isConvex() );
3601 
3602  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,2}, {0,2} } );
3603  CHECK( plc.isConvex() );
3604  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {1,1}, {2,2}, {0,2} } );
3605  CHECK( !plc.isConvex() );
3606 
3607  plc.set( std::vector<Point2d>{ {2,2}, {2,-2}, {-2,-2}, {-2,2} } );
3608  CHECK( plc.isConvex() );
3609  plc.set( std::vector<Point2d>{ {2,2}, {2,-2}, {1,1}, {-2,2} } );
3610  CHECK( !plc.isConvex() );
3611 }
bool isConvex() const
Returns true if polygon is convex.
Definition: homog2d.hpp:7430
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
bool isConvex(const base::PolylineBase< PLT, FPT > &poly)
Returns true if polygon is convex (free function)
Definition: homog2d.hpp:9917
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [76/93]

TEST_CASE ( "Polygon orientation"  ,
""  [polyline-orient] 
)
3614 {
3615  {
3616  CPolyline_<NUMTYPE> pl1;
3617  CPolyline_<NUMTYPE> pl2; // +-----+
3618  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } ); // | |
3619  pl2.set( std::vector<Point2d>{ {0,0}, {0,1}, {2,1}, {2,0} } ); // +-----+
3620  CHECK( pl1 == pl2 ); // is closed, so the points describe the same thing
3621  }
3622  {
3623  OPolyline_<NUMTYPE> pl1;
3624  OPolyline_<NUMTYPE> pl2; // +-----+ +-----+
3625  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } ); // | and | |
3626  pl2.set( std::vector<Point2d>{ {0,0}, {0,1}, {2,1}, {2,0} } ); // +-----+ + +
3627  CHECK( pl1 != pl2 ); // is open, so they are different
3628 
3629  CPolyline_<NUMTYPE> plc1(pl1);
3630  CPolyline_<NUMTYPE> plc2(pl2);
3631  CHECK( plc1 == plc2 );
3632  }
3633  {
3634  std::vector<Point2d> v1{ {0,0}, {1,0}, {1,1} };
3635  std::vector<Point2d> v2{ {1,1}, {1,0}, {0,0} };
3636 
3637  CPolyline_<NUMTYPE> pl1(v1);
3638  CPolyline_<NUMTYPE> pl2(v2);
3639  CHECK( pl1 == pl2 );
3640  OPolyline_<NUMTYPE> po1(v1);
3641  OPolyline_<NUMTYPE> po2(v2);
3642  CHECK( po1 == po2 );
3643  }
3644 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [77/93]

TEST_CASE ( "Polyline basic"  ,
""  [polyline-basic] 
)
3648 {
3649  std::vector<Point2d_<NUMTYPE>> vpts{ {0,0}, {1,0}, {1,1} };
3650 
3651  std::vector<Segment_<NUMTYPE>> vseg_o;
3652  std::vector<Segment_<NUMTYPE>> vseg_c;
3653  vseg_o.emplace_back( Segment_<NUMTYPE>( 0,0, 1,0 ) );
3654  vseg_o.emplace_back( Segment_<NUMTYPE>( 1,0, 1,1 ) );
3655  vseg_c = vseg_o;
3656  vseg_c.emplace_back( Segment_<NUMTYPE>( 1,1, 0,0 ) );
3657 
3658  CPolyline_<NUMTYPE> cpol(vpts);
3659  OPolyline_<NUMTYPE> opol(vpts);
3660  CHECK( cpol.isClosed() );
3661  CHECK( !opol.isClosed() );
3662 
3663  CHECK( cpol.size() == 3 );
3664  CHECK( opol.size() == 3 );
3665 
3666  CHECK( cpol.getPts() == vpts );
3667  CHECK( opol.getPts() == vpts );
3668 
3669  CHECK( cpol.getSegs() == vseg_c );
3670  CHECK( opol.getSegs() == vseg_o );
3671 
3672  std::vector<OSegment_<NUMTYPE>> voseg_o; // oriented segments
3673  std::vector<OSegment_<NUMTYPE>> voseg_c;
3674 
3675  auto os0 = OSegment_<NUMTYPE>( 0,0, 1,0 );
3676  auto os1 = OSegment_<NUMTYPE>( 1,0, 1,1 );
3677  auto os2 = OSegment_<NUMTYPE>( 1,1, 0,0 );
3678  voseg_o.emplace_back( os0 );
3679  voseg_o.emplace_back( os1 );
3680  voseg_c = voseg_o;
3681  voseg_c.emplace_back( os2 );
3682 
3683  CHECK( cpol.getOSegs() == voseg_c );
3684  CHECK( opol.getOSegs() == voseg_o );
3685 
3686  CHECK( cpol.getOSegment(0) == os0 );
3687  CHECK( opol.getOSegment(0) == os0 );
3688 
3689  CHECK( cpol.getOSegment(1) == os1 );
3690  CHECK( opol.getOSegment(1) == os1 );
3691 
3692  CHECK( cpol.getOSegment(2) == os2 );
3693  CHECK_THROWS( opol.getOSegment(2) );
3695 }
std::vector< Segment_< FPT > > getSegs() const
Returns (as a copy) the segments of the polyline.
Definition: homog2d.hpp:6314
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CHECK_THROWS(CPolyline(-5, 5u))
std::vector< OSegment_< FPT > > getOSegs() const
Returns (as a copy) the oriented segments of the polyline.
Definition: homog2d.hpp:6308
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6295
constexpr bool isClosed() const
Definition: homog2d.hpp:6213
CPolyline cpol
Definition: homog2d_test.cpp:4030
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6211
OSegment_< FPT > getOSegment(size_t idx) const
Returns one oriented segment of the polyline.
Definition: homog2d.hpp:6353
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [78/93]

TEST_CASE ( "Polyline fullstep rotation"  ,
""  [polyline-rot] 
)
3699 {
3700  OPolyline_<NUMTYPE> plo;
3701  CPolyline_<NUMTYPE> plc;
3702  OPolyline_<NUMTYPE> plo_ff;
3703  CPolyline_<NUMTYPE> plc_ff;
3704  std::vector<Point2d> vpts{ {0,0}, {2,0}, {1,1} };
3705  {
3706  plo.set( vpts );
3707  plc.set( vpts );
3708  plo.rotate( Rotate::CCW );
3709  plc.rotate( Rotate::CCW );
3710  std::vector<Point2d> vpts2{ {0,0},{0,2},{-1,1} };
3711  OPolyline_<NUMTYPE> plo2( vpts2 );
3712  CPolyline_<NUMTYPE> plc2( vpts2 );
3713  CHECK( plo == plo2 );
3714  CHECK( plc == plc2 );
3715 
3716  plo_ff.set( vpts );
3717  plc_ff.set( vpts );
3718  rotate( plo_ff, Rotate::CCW );
3719  rotate( plc_ff, Rotate::CCW );
3720  CHECK( plo == plo_ff );
3721  CHECK( plc == plc_ff );
3722  }
3723  {
3724  plo.set( vpts );
3725  plc.set( vpts );
3726  plo.rotate( Rotate::VMirror );
3727  plc.rotate( Rotate::VMirror );
3728  std::vector<Point2d> vpts2{ {0,0},{-2,0},{-1,1} };
3729  OPolyline_<NUMTYPE> plo2( vpts2 );
3730  CPolyline_<NUMTYPE> plc2( vpts2 );
3731  CHECK( plo == plo2 );
3732  CHECK( plc == plc2 );
3733  }
3734  {
3735  plo.set( vpts );
3736  plc.set( vpts );
3737  plo.rotate( Rotate::HMirror );
3738  plc.rotate( Rotate::HMirror );
3739  std::vector<Point2d> vpts2{ {0,0},{2,0},{1,-1} };
3740  OPolyline_<NUMTYPE> plo2( vpts2 );
3741  CPolyline_<NUMTYPE> plc2( vpts2 );
3742  CHECK( plo == plo2 );
3743  CHECK( plc == plc2 );
3744  }
3745 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void rotate(Rotate, const Point2d_< FPT2 > &)
Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt.
Definition: homog2d.hpp:7265
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
void rotate(T &prim, Rotate rot)
Rotates the primitive (only available for Polyline and FRect) around (0,0)
Definition: homog2d.hpp:9946
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [79/93]

TEST_CASE ( "Polygon area"  ,
""  [polyline-area] 
)
3748 {
3749  CPolyline_<NUMTYPE> pl1;
3750  {
3751  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } );
3752  CHECK( pl1.size() == 4 );
3753  CHECK( pl1.nbSegs() == 4 );
3754  CHECK( pl1.isSimple() == true );
3755  CHECK( pl1.area() == 2. );
3756  }
3757  {
3758  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,2}, {1,2}, {1,1}, {0,1} } );
3759  CHECK( pl1.size() == 6 );
3760  CHECK( pl1.nbSegs() == 6 );
3761  CHECK( pl1.isSimple() == true );
3762  CHECK( pl1.area() == 3. );
3763  }
3764  OPolyline_<NUMTYPE> plo;
3765  plo.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } );
3766  CHECK( plo.isSimple() == false );
3767  CHECK( plo.area() == 0. );
3768 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6245
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7381
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6211
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
HOMOG2D_INUMTYPE area() const
Returns area of polygon (computed only if necessary)
Definition: homog2d.hpp:7481
Here is the call graph for this function:

◆ TEST_CASE() [80/93]

TEST_CASE ( "Polyline comparison 2"  ,
""  [polyline-comp-2] 
)
3771 {
3772  {
3773  OPolyline_<NUMTYPE> pa,pb;
3774  CHECK( pa == pb );
3775  }
3776  {
3777  CPolyline_<NUMTYPE> pa,pb;
3778  CHECK( pa == pb );
3779  }
3780 
3781  OPolyline_<NUMTYPE> pl2( std::vector<Point2d>{ {7,8},{3,4},{5,6} } );
3782  OPolyline_<NUMTYPE> pl1( std::vector<Point2d>{ {3,4},{5,6},{7,8} } );
3783 
3784  {
3785  OPolyline_<NUMTYPE> p1 = pl1;
3786  OPolyline_<NUMTYPE> p2 = pl2;
3787 
3788  CHECK( p1.isClosed() == false );
3789  CHECK( p1.isNormalized() == false );
3790  CHECK( p2.isNormalized() == false );
3791  CHECK( p1!=p2 );
3792  }
3793  {
3794  CPolyline_<NUMTYPE> p1 = pl1; // build a closed one from an open one
3795  CPolyline_<NUMTYPE> p2 = pl2;
3796 
3797  CHECK( p1.isClosed() == true );
3798  CHECK( p1.isNormalized() == false );
3799  CHECK( p2.isNormalized() == false );
3800  CHECK( (p1==p2) == true );
3801  CHECK( p1.isNormalized() == true );
3802  CHECK( p2.isNormalized() == true );
3803  }
3804  {
3805  CPolyline_<NUMTYPE> p2( std::vector<Point2d>{ {1,2},{1,1},{2,1} } );
3806  CPolyline_<NUMTYPE> p1( std::vector<Point2d>{ {1,1},{2,1},{1,2} } );
3807 
3808  CHECK( p1.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3809  CHECK( p2.getPoint(0) == Point2d_<NUMTYPE>(1,2) );
3810  CHECK( p1 == p2 ); // normalizing
3811  CHECK( p1.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3812  CHECK( p2.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3813  }
3814  {
3815  CPolyline pa, pb;
3816  {
3817 #include "figures_test/polyline_comp_1a.code"
3818  pa = pl;
3819  }
3820  {
3821 #include "figures_test/polyline_comp_1b.code"
3822  pb = pl;
3823  }
3824  CHECK( pa.size() == pb.size() );
3825  CHECK( pa != pb );
3826  }
3827 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6320
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
constexpr bool isClosed() const
Definition: homog2d.hpp:6213
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6211
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [81/93]

TEST_CASE ( "convex hull"  ,
""  [conv_hull] 
)
3915 {
3916  {
3918 
3919  pl.set( FRect_<NUMTYPE>(1,1,3,3) );
3920  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3921 
3922  std::vector<Point2d> v1{ {0,0}, {2,0}, {2,2}, {1,2}, {1,1}, {0,1} };
3923  pl.set( v1 );
3924  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3925 
3926  std::rotate( v1.begin(), v1.begin()+1, v1.end() );
3927  pl.set( v1 );
3928  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 5 );
3929 
3930  std::rotate( v1.begin(), v1.begin()+1, v1.end() );
3931  pl.set( v1 );
3932  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 4 );
3933  }
3934  {
3935 #include "figures_test/polyline_chull_1.code"
3936  auto vp = pl.getPts();
3937  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3938  auto vout = priv::chull::sortPoints( vp, 0 );
3939  CHECK( vout == std::vector<size_t>{ 0,1,2,3 } );
3940  auto ch = convexHull( pl );
3941  CHECK( ch == CPolyline(
3942  std::vector<Point2d>{
3943  {0,0},{3,0},{0,3}
3944  }
3945  )
3946  );
3947  }
3948  {
3949  CPolyline pl1;
3950  auto ch1 = convexHull( pl1 );
3951  CHECK( ch1.size() == 0 );
3952  auto ch2 = pl1.convexHull();
3953  CHECK( ch2.size() == 0 );
3954  }
3955  {
3956  CPolyline pl1( std::vector<Point2d>{ {1,1}, {2,2} });
3957  auto ch1 = convexHull( pl1 );
3958  CHECK( ch1.size() == 2 );
3959  auto ch2 = pl1.convexHull();
3960  CHECK( ch2.size() == 2 );
3961  }
3962 }
std::vector< size_t > sortPoints(const std::vector< Point2d_< FPT >> &in, size_t piv_idx)
Sorts points by angle between the lines with horizontal axis.
Definition: homog2d.hpp:11458
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline_< FPT > convexHull() const
Return convex hull (member function implementation)
Definition: homog2d.hpp:11623
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12398
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6461
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6295
void rotate(T &prim, Rotate rot)
Rotates the primitive (only available for Polyline and FRect) around (0,0)
Definition: homog2d.hpp:9946
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
size_t getPivotPoint(const std::vector< Point2d_< FPT >> &in)
Used int the convex hull algorithm.
Definition: homog2d.hpp:11448
CPolyline_< FPT > convexHull(const base::PolylineBase< CT, FPT > &input)
Compute Convex Hull of a Polyline (free function)
Definition: homog2d.hpp:11536
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Here is the call graph for this function:

◆ TEST_CASE() [82/93]

TEST_CASE ( "nearest/farthest points"  ,
""  [nfp] 
)
3974 {
3975 // 1 - make sure calling with empty container throws
3976  std::vector<Point2d_<NUMTYPE>> vec;
3977  std::vector<Point2d_<NUMTYPE>> lst;
3978  std::array<Point2d_<NUMTYPE>,0> arr0; // very unlikely, but... who knows?
3979  checkSizeNF( Point2d_<NUMTYPE>(), vec );
3980  checkSizeNF( Point2d_<NUMTYPE>(), lst );
3981  checkSizeNF( Point2d_<NUMTYPE>(), arr0 );
3982 
3983 // 2 - make sure calling with container holding only 1 point also throws
3984  vec.emplace_back( Point2d_<NUMTYPE>() ); // add point (0,0)
3985  lst.emplace_back( Point2d_<NUMTYPE>() );
3986  std::array<Point2d_<NUMTYPE>,1> arr;
3987 
3988  checkSizeNF( Point2d_<NUMTYPE>(), vec );
3989  checkSizeNF( Point2d_<NUMTYPE>(), lst );
3990  checkSizeNF( Point2d_<NUMTYPE>(), arr );
3991 
3992 // 3 - check behavior if query point is in the container (only for vector)
3993  {
3994  Point2d_<NUMTYPE> pt1(1,1);
3995  Point2d_<NUMTYPE> pt0;
3996  vec.emplace_back( pt1 );
3997  auto resN = findNearestPoint( pt0, vec ); // check for (0,0)
3998  auto resF = findFarthestPoint( pt0, vec );
3999  CHECK( resN == 1 ); // both will return
4000  CHECK( resF == 1 ); // second point
4001 
4002  resN = findNearestPoint( pt1, vec ); // check for (1,1)
4003  resF = findFarthestPoint( pt1, vec );
4004  CHECK( resN == 0 ); // both will return
4005  CHECK( resF == 0 ); // first point
4006 
4007  auto pres = findNearestFarthestPoint( pt0, vec );
4008  CHECK( pres.first == 1 );
4009  CHECK( pres.second == 1 );
4010  auto pres2 = findNearestFarthestPoint( pt1, vec );
4011  CHECK( pres2.first == 0 );
4012  CHECK( pres2.second == 0 );
4013  }
4014 
4015 // 4 - check general behavior
4016  { // 0 1 2 3 4
4017  std::vector<Point2d_<NUMTYPE>> vec2{ {0,0}, {3,0}, {4,0}, {5,6}, {7,8} };
4018  Point2d_<NUMTYPE> qpt(4,5);
4019  auto pres = findNearestFarthestPoint( qpt, vec2 );
4020  auto resN = findNearestPoint( qpt, vec2 );
4021  auto resF = findFarthestPoint( qpt, vec2 );
4022  CHECK( pres.first == resN );
4023  CHECK( pres.second == resF );
4024  CHECK( 3 == resN );
4025  CHECK( 0 == resF );
4026  }
4027 }
auto findNearestFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns indexes of points in container cont that are nearest/farthest.
Definition: homog2d.hpp:11167
void checkSizeNF(const PT &pt, const CONT &cont)
Definition: homog2d_test.cpp:3966
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
size_t findFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns index of point in container cont that is the farthest to pt.
Definition: homog2d.hpp:11156
size_t findNearestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns index of point in container cont that is the nearest to pt.
Definition: homog2d.hpp:11148
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [83/93]

TEST_CASE ( "pts_inside"  ,
""  [ptsins] 
)
Todo:
20250201: add tests cases
4061 {
4062  OPolyline opol;
4063 
4064 }
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364

◆ TEST_CASE() [84/93]

TEST_CASE ( "variant conversion tests"  ,
""  [varconv] 
)
4073 {
4075  var = Circle_<NUMTYPE>{};
4077  // TODO
4078 }
A circle.
Definition: homog2d.hpp:378
Convert std::variant object into the underlying type.
Definition: homog2d.hpp:1093
std::variant< Segment_< FPT >, OSegment_< FPT >, Point2d_< FPT >, Line2d_< FPT >, Circle_< FPT >, Ellipse_< FPT >, FRect_< FPT >, CPolyline_< FPT >, OPolyline_< FPT > > CommonType_
A variant type, holding all possible types. Used to achieve runtime polymorphism. ...
Definition: homog2d.hpp:424

◆ TEST_CASE() [85/93]

TEST_CASE ( "variant-based polymorphism"  ,
""  [polymorph_1] 
)
4081 {
4082  std::vector<CommonType_<NUMTYPE>> vvar;
4083  vvar.push_back( Circle_<NUMTYPE>{} );
4084  vvar.push_back( Segment_<NUMTYPE>{} );
4085  vvar.push_back( Line2d_<NUMTYPE>{} );
4086 
4087  {
4088  auto var0 = vvar[0];
4090  CHECK( std::visit( fct::TypeFunct{}, var0 ) == Type::Circle );
4091  CHECK( c == Circle() );
4092 
4093  auto var1 = vvar[1];
4095  CHECK( type( var1 ) == Type::Segment );
4096  CHECK( s == Segment() );
4097 
4098  auto var2 = vvar[2];
4100  CHECK( type( var2 ) == Type::Line2d );
4101  }
4102 }
A circle.
Definition: homog2d.hpp:378
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12376
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Type type(const T &elem)
Free function. Returns the type of object or variant.
Definition: homog2d.hpp:10190
Convert std::variant object into the underlying type.
Definition: homog2d.hpp:1093
A functor to get the type of an object in a std::variant, call with std::visit()
Definition: homog2d.hpp:979
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [86/93]

TEST_CASE ( "SVG_Import_1"  ,
""  [svg_import_1] 
)
Note
Here, we use only the "double" type, because that is the one used on import
4112 {
4114  {
4115  Circle c( 50,50,20);
4116  img::Image<img::SvgImage> im(200,200);
4117  c.draw( im );
4118  im.write( "BUILD/test_svg_11.svg" );
4119 
4120  tinyxml2::XMLDocument doc; // load the file that we just created
4121  doc.LoadFile( "BUILD/test_svg_11.svg" );
4122 
4123  h2d::svg::Visitor visitor;
4124  doc.Accept( &visitor );
4125  const auto& data = visitor.get();
4126  CHECK( data.size() == 1 );
4127  auto elem = data.at(0);
4128  CHECK( type( elem ) == Type::Circle );
4130  CHECK( cir.radius() == 20 );
4131  }
4132  { // this test makes sure the <g> element is ignored
4133  tinyxml2::XMLDocument doc;
4134  doc.LoadFile( "misc/other/test_svg_import_1.svg" );
4135  h2d::svg::Visitor visitor;
4136  doc.Accept( &visitor );
4137  const auto& data = visitor.get();
4138  CHECK( data.size() == 3 );
4139  for( const auto& elem: data )
4140  CHECK( type( elem ) == Type::Circle );
4141  }
4142  { // read a file with 3 circles, one rect, one segment and a polygon
4143  tinyxml2::XMLDocument doc;
4144  doc.LoadFile( "misc/other/test_svg_import_2.svg" );
4145  h2d::svg::Visitor visitor;
4146  doc.Accept( &visitor );
4147  const auto& data = visitor.get();
4148  CHECK( data.size() == 6 );
4149 
4150  CHECK( type( data.at(3) ) == Type::Segment );
4151  CHECK( type( data.at(4) ) == Type::FRect );
4152  CHECK( type( data.at(5) ) == Type::CPolyline );
4153  }
4154 }
A circle.
Definition: homog2d.hpp:378
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12395
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12388
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12392
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Type type(const T &elem)
Free function. Returns the type of object or variant.
Definition: homog2d.hpp:10190
Convert std::variant object into the underlying type.
Definition: homog2d.hpp:1093
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12398
Visitor class, derived from the tinyxml2 visitor class. Used to import SVG data.
Definition: homog2d.hpp:12864
img::Image< img::SvgImage > im(300, 400)
const std::vector< CommonType_< double > > & get() const
Used to access the data once the file has been read.
Definition: homog2d.hpp:12904
Opaque data structure, will hold the image type, depending on back-end library. This type is the one ...
Definition: homog2d.hpp:712
FPT & radius()
Definition: homog2d.hpp:3256
Circle cir
Definition: homog2d_test.cpp:4036
Here is the call graph for this function:

◆ TEST_CASE() [87/93]

TEST_CASE ( "SVG Import Ellipse ,
""  [svg_import_ell] 
)
4157 {
4158  tinyxml2::XMLDocument doc;
4159  doc.LoadFile( "misc/other/test_svg_import_3.svg" );
4160  h2d::svg::Visitor visitor;
4161  doc.Accept( &visitor );
4162  const auto& data = visitor.get();
4163  CHECK( data.size() == 3 );
4164  for( const auto& p: data )
4165  {
4166  if( type( p ) == Type::Ellipse )
4167  {
4168  Ellipse ell( 150, 100, 60, 15, 20*M_PI/180. );
4169  const EllipseD ell2 = fct::VariantUnwrapper{ p };
4170  CHECK( ell == ell2 );
4171  }
4172  }
4173 }
Ellipse_< HOMOG2D_INUMTYPE > Ellipse
Default ellipse type.
Definition: homog2d.hpp:12402
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
#define M_PI
Definition: homog2d.hpp:235
Type type(const T &elem)
Free function. Returns the type of object or variant.
Definition: homog2d.hpp:10190
Convert std::variant object into the underlying type.
Definition: homog2d.hpp:1093
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Visitor class, derived from the tinyxml2 visitor class. Used to import SVG data.
Definition: homog2d.hpp:12864
Ellipse ell
Definition: homog2d_test.cpp:4037
const std::vector< CommonType_< double > > & get() const
Used to access the data once the file has been read.
Definition: homog2d.hpp:12904
Here is the call graph for this function:

◆ TEST_CASE() [88/93]

TEST_CASE ( "SVG Import path 1"  ,
""  [svg_import_path_1] 
)
4176 {
4177  { // empty string
4178  const char* s1 = "";
4180  }
4181  {
4182  const char* s1 ="10 20 30 40";
4183  const auto& res = svg::svgp::parsePath( s1 );
4184  CHECK( res.first.size() == 1 ); // one vector
4185  CHECK( res.first[0].size() == 2 ); // holding two points
4186  CHECK( res.first[0][0] == Point2d(10,20) );
4187  CHECK( res.first[0][1] == Point2d(30,40) );
4188  CHECK( res.second == false );
4189  }
4190 
4191  {
4192  const char* s1 ="10 20 30 40z";
4193  auto res = svg::svgp::parsePath( s1 );
4194  CHECK( res.first.size() == 1 );
4195  CHECK( res.first[0].size() == 2 );
4196  CHECK( res.second == true );
4197  }
4198  {
4199  const char* s1 ="10 20 m 1 2 3 4z"; //relative and "Move To" (=>so two vectors in output)
4200  auto res = svg::svgp::parsePath( s1 );
4201  CHECK( res.first.size() == 2 );
4202  CHECK( res.first[0].size() == 1 );
4203  CHECK( res.first[1].size() == 2 );
4204  CHECK( res.first[0][0] == Point2d(10,20) );
4205  CHECK( res.first[1][0] == Point2d(11,22) );
4206  CHECK( res.first[1][1] == Point2d(14,26) );
4207  CHECK( res.second == true );
4208  }
4209  {
4210  const char* s1 ="10 20 H 30 40"; //horizontal line
4211  auto res = svg::svgp::parsePath( s1 );
4212  CHECK( res.first.size() == 1 );
4213  CHECK( res.first[0].size() == 3 );
4214  CHECK( res.first[0][0] == Point2d(10,20) );
4215  CHECK( res.first[0][1] == Point2d(30,20) );
4216  CHECK( res.first[0][2] == Point2d(40,20) );
4217  CHECK( res.second == false);
4218  }
4219  {
4220  const char* s1 ="10"; // missing second value
4222  }
4223  {
4224  const char* s1 ="10 20 30"; // missing second value
4226  }
4227  {
4228  const char* s1 ="M10 20 C 30"; // C command not handled
4230  }
4231 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
auto parsePath(const char *s)
Parse a SVG "path" string and convert it to a vector holding a set (vector) of points.
Definition: homog2d.hpp:12796
CHECK_THROWS(CPolyline(-5, 5u))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [89/93]

TEST_CASE ( "boost geometry point import"  ,
""  [bg-pt-import] 
)
4241 {
4242  namespace bg = boost::geometry;
4243  bg::model::point<double, 2, boost::geometry::cs::cartesian> ptb1(3,4);
4244  bg::model::d2::point_xy<double> ptb2(5,6);
4245  Point2d_<NUMTYPE> pt1(ptb1);
4246  Point2d_<NUMTYPE> pt2(ptb2);
4247  CHECK( pt1 == Point2d_<NUMTYPE>(3,4) );
4248  CHECK( pt2 == Point2d_<NUMTYPE>(5,6) );
4249 
4250  pt1 = ptb1; // using assignment operator
4251  pt2 = ptb2;
4252  CHECK( pt1 == Point2d_<NUMTYPE>(3,4) );
4253  CHECK( pt2 == Point2d_<NUMTYPE>(5,6) );
4254 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [90/93]

TEST_CASE ( "boost geometry point export"  ,
""  [bg-pt-export] 
)
4257 {
4258  Point2d_<NUMTYPE> ref1(3,4);
4259  Point2d_<NUMTYPE> ref2(5,6);
4260  namespace bg = boost::geometry;
4261  using point_t1 = bg::model::point<double, 2, bg::cs::cartesian>;
4262  using point_t2 = bg::model::d2::point_xy<double>;
4263 
4264  auto pt1 = getPt<point_t1>( ref1 );
4265  auto pt2 = getPt<point_t2>( ref2 );
4266  CHECK( bg::get<0>(pt1) == ref1.getX() );
4267  CHECK( bg::get<0>(pt2) == ref2.getX() );
4268 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

◆ TEST_CASE() [91/93]

TEST_CASE ( "boost geometry vector point export"  ,
""  [bg-vpt-export] 
)
4271 {
4272  namespace bg = boost::geometry;
4273  std::vector<Point2d> vin;
4274  vin.push_back( Point2d(0.0, 0.0) );
4275  vin.push_back( Point2d(0.0, 5.0));
4276  vin.push_back( Point2d(5.0, 5.0));
4277  auto vout = getPts<bg::model::d2::point_xy<float>>(vin); // convert to a vector of boost geometry points
4278  CHECK( vout.size() == 3 );
4279 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
Here is the call graph for this function:

◆ TEST_CASE() [92/93]

TEST_CASE ( "Opencv build H"  ,
""  [test_opencv2] 
)
4290 {
4291  std::vector<Point2d_<NUMTYPE>> v1(4);
4292  std::vector<Point2d_<NUMTYPE>> v2(4);
4294  H.buildFrom4Points( v1, v2 );
4295  buildFrom4Points( v1, v2 );
4296 }
Homogr_< FPT > buildFrom4Points(const std::vector< Point2d_< FPT >> &vpt1, const std::vector< Point2d_< FPT >> &vpt2, int method=1)
Build Homography from 2 sets of 4 points (free function)
Definition: homog2d.hpp:4768
void buildFrom4Points(const std::vector< Point2d_< FPT >> &, const std::vector< Point2d_< FPT >> &, int method=1)
Build Homography from 2 sets of 4 points.
Definition: homog2d.hpp:4793
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
Here is the call graph for this function:

◆ TEST_CASE() [93/93]

TEST_CASE ( "Opencv binding"  ,
""  [test_opencv] 
)
4299 {
4300  cv::Mat mat_64 = cv::Mat::eye(3, 3, CV_64F);
4301  cv::Mat mat_32 = cv::Mat::eye(3, 3, CV_32F);
4302  INFO( "assignment operator()" )
4303  {
4304  cv::Mat cvmat = cv::Mat::ones(3,3, CV_32F );
4305  Homogr H;
4306  H = cvmat;
4307  CHECK( H.value(0,0) == 1.);
4308  CHECK( H.value(1,1) == 1.);
4309  CHECK( H.value(1,0) == 1.);
4310  CHECK( H.value(0,1) == 1.);
4311 
4312  cv::Mat cvmat2 = cv::Mat::ones(3,3, CV_32F );
4313  Homogr H2 = cvmat;
4314  CHECK( H2.value(0,0) == 1.);
4315  CHECK( H2.value(1,1) == 1.);
4316  CHECK( H2.value(1,0) == 1.);
4317  CHECK( H2.value(0,1) == 1.);
4318 
4319  H = mat_64;
4320  CHECK( H.value(0,0) == 1.);
4321  CHECK( H.value(1,1) == 1.);
4322  CHECK( H.value(1,0) == 0.);
4323  CHECK( H.value(0,1) == 0.);
4324 
4325  H = mat_32;
4326  CHECK( H.value(0,0) == 1.);
4327  CHECK( H.value(1,1) == 1.);
4328  CHECK( H.value(1,0) == 0.);
4329  CHECK( H.value(0,1) == 0.);
4330  }
4331  INFO( "default copyTo()" )
4332  {
4333  Homogr H;
4334  cv::Mat mat;
4335  CHECK_THROWS( H.copyTo( mat, 111 ) );
4336  CHECK_NOTHROW( H.copyTo( mat ) );
4337  CHECK( (
4338  (mat.at<double>(0,0) == 1.0)
4339  && (mat.at<double>(0,1) == 0.0)
4340  && (mat.at<double>(0,2) == 0.0)
4341  ) );
4342  CHECK( mat.channels() == 1 );
4343  CHECK( mat.type() == CV_64F );
4344  }
4345  INFO( "copyTo() with CV_64F" )
4346  {
4347  Homogr H;
4348  cv::Mat mat;
4349  H.copyTo( mat, CV_64F );
4350  CHECK( (
4351  (mat.at<double>(0,0) == 1.0)
4352  && (mat.at<double>(0,1) == 0.0)
4353  && (mat.at<double>(0,2) == 0.0)
4354  ) );
4355  CHECK( mat.channels() == 1 );
4356  CHECK( mat.type() == CV_64F );
4357  }
4358  INFO( "copyTo() with CV_32F" )
4359  {
4360  Homogr H;
4361  cv::Mat mat;
4362  H.copyTo( mat, CV_32F );
4363  CHECK( (
4364  (mat.at<float>(0,0) == 1.0)
4365  && (mat.at<float>(0,1) == 0.0)
4366  && (mat.at<float>(0,2) == 0.0)
4367  ) );
4368  CHECK( mat.channels() == 1 );
4369  CHECK( mat.type() == CV_32F );
4370  }
4371  INFO( "Copy to OpenCv points" )
4372  {
4373  Point2d_<NUMTYPE> pt(1.,2.);
4374  { // free function
4375  cv::Point2d cvpt1 = getCvPtd( pt ); // double
4376  CHECK( (cvpt1.x == 1. && cvpt1.y == 2.) );
4377  cv::Point2f cvpt2 = getCvPtf( pt ); // float
4378  CHECK( (cvpt2.x == 1. && cvpt2.y == 2.) );
4379  cv::Point2i cvpt3 = getCvPti( pt ); // integer point
4380  CHECK( (cvpt3.x == 1 && cvpt3.y == 2) );
4381 
4382  auto cvpt_1 = getPt<cv::Point2d>( pt );
4383  auto cvpt_2 = getPt<cv::Point2f>( pt );
4384  auto cvpt_3 = getPt<cv::Point2i>( pt );
4385  }
4386  {
4387  cv::Point2d cvpt1 = pt.getCvPtd() ;
4388  CHECK( (cvpt1.x == 1. && cvpt1.y == 2.) );
4389  cv::Point2f cvpt2 = pt.getCvPtf() ;
4390  CHECK( (cvpt2.x == 1. && cvpt2.y == 2.) );
4391  cv::Point2i cvpt3 = pt.getCvPti() ; // integer point
4392  CHECK( (cvpt3.x == 1 && cvpt3.y == 2 ) );
4393 
4394  auto cvpt_1 = pt.getPt<cv::Point2d>();
4395  auto cvpt_2 = pt.getPt<cv::Point2f>();
4396  auto cvpt_3 = pt.getPt<cv::Point2i>();
4397  }
4398  { // input: vector of "double" points
4399  // converted into "float" Opencv points
4400  std::vector<Point2d> v{ Point2d(1,2), Point2d(5,6), Point2d(3,4) };
4401  auto vcv1 = getPts<cv::Point2d>( v );
4402  CHECK( vcv1.size() == 3 );
4403  auto vcv2 = getPts<cv::Point2f>( v );
4404  CHECK( vcv2.size() == 3 );
4405  auto vcv3 = getPts<cv::Point2i>( v );
4406  CHECK( vcv3.size() == 3 );
4407  }
4408  }
4409  INFO( "Fetch from OpenCv points" )
4410  {
4411  cv::Point2d ptd(1,2);
4412  cv::Point2f ptf(1,2);
4413  cv::Point2f pti(1,2);
4414  { // test of constructor
4415  Point2d p1(ptd);
4416  CHECK(( p1.getX() == 1. && p1.getY() == 2. ));
4417  Point2d_<NUMTYPE> p2(ptf);
4418  CHECK(( p2.getX() == 1. && p2.getY() == 2. ));
4419  Point2d_<NUMTYPE> p3(pti);
4420  CHECK(( p3.getX() == 1. && p3.getY() == 2. ));
4421  }
4422  { // test of assignment operator
4423  Point2d p1 = ptd;
4424  CHECK(( p1.getX() == 1 && p1.getY() == 2. ));
4425  Point2d_<NUMTYPE> p2 = ptf;
4426  CHECK(( p2.getX() == 1 && p2.getY() == 2. ));
4427  Point2d_<NUMTYPE> p3 = pti;
4428  CHECK(( p3.getX() == 1 && p3.getY() == 2. ));
4429  }
4430  }
4431  INFO( "Build line using OpenCv points" )
4432  {
4433  Line2d_<NUMTYPE> lia( cv::Point2d(100,200) );
4434 // Line2d_<NUMTYPE> lib( Point2d(100,200) );
4435 // CHECK( lia == lib );
4436  }
4437 }
cv::Point2d getCvPtd(const Point2d_< FPT > &pt)
Free function to return an OpenCv point (double)
Definition: homog2d.hpp:4592
cv::Point2f getCvPtf(const Point2d_< FPT > &pt)
Free function to return an OpenCv point (float)
Definition: homog2d.hpp:4599
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
A 2D homography, defining a planar transformation.
Definition: homog2d.hpp:369
cv::Point2i getCvPti(const Point2d_< FPT > &pt)
Free function to return an OpenCv point (integer)
Definition: homog2d.hpp:4606
ANY getPt() const
Generic transformation into any other point type, as long as it provides a 2-args constructor (is the...
Definition: homog2d.hpp:4198
void copyTo(cv::Mat &, int type=CV_64F) const
Copy matrix to Opencv cv::Mat.
Definition: homog2d.hpp:11643
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12379
CHECK_THROWS(CPolyline(-5, 5u))
const FPT & value(size_t r, size_t c) const
Definition: homog2d.hpp:1473
cv::Point2i getCvPtf() const
Definition: homog2d.hpp:4436
cv::Point2i getCvPti() const
Definition: homog2d.hpp:4434
cv::Point2i getCvPtd() const
Definition: homog2d.hpp:4435
HOMOG2D_INUMTYPE getX() const
Definition: homog2d.hpp:4129
Point2d pt
Definition: homog2d_test.cpp:4034
HOMOG2D_INUMTYPE getY() const
Definition: homog2d.hpp:4134
Base class, will be instanciated as Point2d_ or Line2d_.
Definition: homog2d.hpp:365
Here is the call graph for this function:

Variable Documentation

◆ cir

Circle cir

◆ cpol

CPolyline cpol
Initial value:
{
OPolyline opol
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364

◆ ell

Ellipse ell

◆ g_epsilon

double g_epsilon = std::numeric_limits<NUMTYPE>::epsilon()*10000.

◆ li

Line2d li

◆ pol

CPolyline pol(5, 5u)

◆ pt

Point2d pt

◆ rect

FRect rect

◆ seg

Segment seg