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 FPT , typename SEG >
auto helper_test_seg_intersect (Line2d_< FPT > li, const SEG &seg, bool doesIntersects)
 
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 
)
3985 {
3986  CHECK_THROWS( findFarthestPoint( pt, cont ) );
3987  CHECK_THROWS( findNearestPoint( pt, cont ) );
3989 }
auto findNearestFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns indexes of points in container cont that are nearest/farthest.
Definition: homog2d.hpp:11171
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:11160
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:11152
Point2d pt
Definition: homog2d_test.cpp:4052
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:4227
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:

◆ helper_test_seg_intersect()

template<typename FPT , typename SEG >
auto helper_test_seg_intersect ( Line2d_< FPT >  li,
const SEG &  seg,
bool  doesIntersects 
)
2181 {
2182  CHECK( li.intersects( seg )() == doesIntersects );
2183  CHECK( seg.intersects( li )() == doesIntersects );
2184  auto ri1 = li.intersects( seg );
2185  auto ri2 = seg.intersects( li );
2186  CHECK( ri1.size() == (doesIntersects?1:0) );
2187  CHECK( ri2.size() == (doesIntersects?1:0) );
2188  if( !doesIntersects )
2189  {
2190  CHECK_THROWS( ri1.get() );
2191  CHECK_THROWS( ri2.get() );
2192  }
2193  return std::make_pair( ri1, ri2 );
2194 }
Segment seg
Definition: homog2d_test.cpp:4051
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:8209
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4289
CHECK_THROWS(CPolyline(-5, 5u))
Here is the call graph for this function:
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

3903 {
3904  FRect r; local_draw_test2( im, r );
3905  Segment s(50,50,100,100);
3906  local_draw_test2( im, s );
3907  Circle c; local_draw_test2( im, c );
3908  Line2d li; local_draw_test2( im, li );
3909  Point2d pt; local_draw_test2( im, pt );
3910  Ellipse el; local_draw_test2( im, el );
3911  CPolyline cp; local_draw_test2( im, cp );
3912  OPolyline op; local_draw_test2( im, op );
3913 
3914  im.write( fn );
3915 }
A circle.
Definition: homog2d.hpp:378
void write(std::string) const
Definition: homog2d.hpp:752
Line2d li
Definition: homog2d_test.cpp:4053
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:3864
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:4052
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()

3865 {
3866  t.draw( im );
3867  im.draw( t );
3868  draw( im, t );
3869 
3870  img::DrawParams dp;
3871  t.draw( im, dp );
3872  im.draw( t, dp );
3873  draw( im, t, dp );
3874 
3875  std::vector<T> v;
3876  t.translate( 50,20 );
3877  v.push_back(t);
3878  t.translate( 50,20 );
3879  v.push_back(t);
3880  draw( im, v );
3881  draw( im, v, dp );
3882 
3883  std::list<T> l;
3884  l.push_back(t);
3885  l.push_back(t);
3886  draw( im, l );
3887  draw( im, l, dp );
3888 
3889  std::array<T,2> a;
3890  a[0]=t;
3891  a[1]=t;
3892  draw( im, a );
3893  draw( im, a, dp );
3894 }
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:1229
#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:1266
Here is the call graph for this function:

◆ polytest_1()

template<typename T , typename U >
void polytest_1 ( const base::PolylineBase< T, U > &  pl1)
3265 {
3266  CHECK( pl1.isSimple() == false );
3267  CHECK( isSimple(pl1) == false );
3268 
3269  CHECK( pl1.size() == 0 );
3270  CHECK( size(pl1) == 0 );
3271 
3272  CHECK( pl1.nbSegs() == 0 );
3273  CHECK( nbSegs(pl1) == 0 );
3274 
3275  CHECK( pl1.length() == 0 );
3276  CHECK( length(pl1) == 0 );
3277 
3278  CHECK( pl1.area() == 0 );
3279  CHECK( area(pl1) == 0 );
3280 
3281  CHECK_THROWS( centroid(pl1) ); // unable
3282  CHECK_THROWS( pl1.centroid() ); // unable
3283 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6249
HOMOG2D_INUMTYPE length() const
Returns length of Polyline.
Definition: homog2d.hpp:7469
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
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:10227
base::LPBase< typ::IsPoint, FPT > centroid(const base::PolylineBase< PLT, FPT > &pl)
Returns centroid of Polyline (free function)
Definition: homog2d.hpp:10911
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10257
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10242
size_t nbSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the number of segments (free function)
Definition: homog2d.hpp:9931
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
LPBase< typ::IsPoint, HOMOG2D_INUMTYPE > centroid() const
Compute centroid of polygon.
Definition: homog2d.hpp:7522
HOMOG2D_INUMTYPE area() const
Returns area of polygon (computed only if necessary)
Definition: homog2d.hpp:7485
bool isSimple(const base::PolylineBase< PLT, FPT > &pl)
Returns true if is a polygon (free function)  
Definition: homog2d.hpp:9911
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:1379
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:10212
Dtype dtype() const
Get numerical data type as a Dtype value, can be stringified with h2d::getString(Dtype) ...
Definition: homog2d.hpp:1372
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:10956
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:4053
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12380
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:12383
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3892
Point2d pt
Definition: homog2d_test.cpp:4052
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:4051
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12380
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:12383
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:5201
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:5256
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:4133
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:4207
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:4051
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Ellipse ell
Definition: homog2d_test.cpp:4055
CPolyline cpol
Definition: homog2d_test.cpp:4048
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:4052
Circle cir
Definition: homog2d_test.cpp:4054
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:1229
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4227
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:4053
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:9833
Point2d pt
Definition: homog2d_test.cpp:4052
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:8882
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9208
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:4075
HOMOG2D_INUMTYPE getAngle(const LPBase< T, FPT2 > &other) const
Line2d li
Definition: homog2d_test.cpp:4053
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8835
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4227
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:12383
Point2d pt
Definition: homog2d_test.cpp:4052
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:1229
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:4665
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8835
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3892
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:4052
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:9208
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:10973
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
bool isParallelTo(const Line2d_< FPT2 > &) const
Definition: homog2d.hpp:9232
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:8972
static HOMOG2D_INUMTYPE & nullAngleValue()
Definition: homog2d.hpp:1239
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4227
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:1229
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
HOMOG2D_INUMTYPE getCoord(GivenCoord gc, FPT2 other) const
Definition: homog2d.hpp:8835
HOMOG2D_INUMTYPE distTo(const Point2d_< FPT2 > &pt) const
overload for line to point distance
Definition: homog2d.hpp:4227
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:9208
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:10997
const FPT & value(size_t r, size_t c) const
Definition: homog2d.hpp:1507
Hmatrix_ & setRotation(T theta)
Sets the matrix as a rotation with an angle theta (radians)
Definition: homog2d.hpp:1898
static HOMOG2D_INUMTYPE & nullAngleValue()
Definition: homog2d.hpp:1239
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:1874
void applyTo(T &) const
Apply homography to a vector/array/list (type T) of points or lines.
Definition: homog2d.hpp:9567
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:9827
Line2d li
Definition: homog2d_test.cpp:4053
FPT getX(const Point2d_< FPT > &pt)
Definition: homog2d.hpp:9824
Hmatrix_ & setRotation(T theta)
Sets the matrix as a rotation with an angle theta (radians)
Definition: homog2d.hpp:1898
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:1535
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:1816
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:1874
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:1931
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:1912
Hmatrix_ & addTranslation(T tx, T ty)
Adds a translation tx,ty to the matrix.
Definition: homog2d.hpp:1864
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:1898
Point2d pt
Definition: homog2d_test.cpp:4052
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:1912
Hmatrix_ & addTranslation(T tx, T ty)
Adds a translation tx,ty to the matrix.
Definition: homog2d.hpp:1864
Hmatrix_ & addRotation(T theta)
Adds a rotation with an angle theta (radians) to the matrix.
Definition: homog2d.hpp:1888
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:4089
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
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:9208
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:1346
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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:5149
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:3007
bool isInside(const Circle_< FPT2 > &other) const
Returns true if circle is inside other circle.
Definition: homog2d.hpp:3441
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:4350
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:6600
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:12383
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:3892
CPolyline cpol
Definition: homog2d_test.cpp:4048
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:4350
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4052
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:4053
Ellipse as a conic in matrix form.
Definition: homog2d.hpp:380
Ellipse ell
Definition: homog2d_test.cpp:4055
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4350
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:3892
bool isInside(const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2) const
Point is inside flat rectangle.
Definition: homog2d.hpp:4350
Point2d pt
Definition: homog2d_test.cpp:4052
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:12396
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:4051
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
Segment_< typename T1::FType > getSegment(const T1 &c1, const T2 &c2)
Free function, returns segment between two circle centers (or ellipse)
Definition: homog2d.hpp:10692
HOMOG2D_INUMTYPE length() const
Get segment length.
Definition: homog2d.hpp:5051
PointPair_< FPT > getPts() const
Returns the points of segment as a std::pair.
Definition: homog2d.hpp:5201
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:8209
detail::IntersectM< FPT > intersects(const T &other) const
Polyline intersection with Line, Segment, FRect, Circle.
Definition: homog2d.hpp:6572
detail::IntersectM< FPT > intersects(const Line2d_< FPT2 > &line) const
FRect/Line intersection.
Definition: homog2d.hpp:3047
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4289
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:3472
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:4289
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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:8209
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
void set(const Point2d_< FP1 > &p1, const Point2d_< FP2 > &p2)
Setter.
Definition: homog2d.hpp:4964
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:12383
detail::Intersect< detail::Inters_2, FPT > intersects(const Line2d_< FPT2 > &li) const
Circle/Line intersection.
Definition: homog2d.hpp:3472
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:9872
detail::RectArea< FPT1 > intersectArea(const FRect_< FPT1 > &r1, const FRect_< FPT2 > &r2)
Free function, see FRect_::intersectArea()
Definition: homog2d.hpp:9881
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
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:7717
detail::IntersectM< FPT > intersects(const Line2d_< FPT2 > &line) const
FRect/Line intersection.
Definition: homog2d.hpp:3047
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12402
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
A Flat Rectangle, modeled by its two opposite points.
Definition: homog2d.hpp:379
HOMOG2D_INUMTYPE width() const
Definition: homog2d.hpp:2781
HOMOG2D_INUMTYPE height() const
Definition: homog2d.hpp:2780
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:9860
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:12383
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:12383
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:3472
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:4289
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
2197 {
2198  Line2d_<NUMTYPE> li; // vertical line x=0
2199  { // Segment: NO intersection
2200  Segment_<NUMTYPE> seg( 1,0,2,0);
2201  helper_test_seg_intersect( li, seg, false );
2202  }
2203  { // OSegment: NO intersection
2204  OSegment_<NUMTYPE> seg( 1,0,2,0);
2205  helper_test_seg_intersect( li, seg, false );
2206  }
2207  { // INTERSECTION
2208  Segment_<NUMTYPE> seg; // (0,0 -- (1,1)
2209  auto pri = helper_test_seg_intersect( li, seg, true );
2210  CHECK( pri.first.get() == Point2d(0,0) );
2211  CHECK( pri.second.get() == Point2d(0,0) );
2212  }
2213  {
2214  Segment_<NUMTYPE> seg( 0,0, 0,2 ); // vertical x=0
2215  CHECK( !li.intersects( seg )() );
2216  CHECK( !seg.intersects( li )() );
2217  }
2218  {
2219  Segment_<NUMTYPE> seg( 1,0, 1,2 );
2220  CHECK( !li.intersects( seg )() );
2221  CHECK( !seg.intersects( li )() );
2222  }
2223 }
Segment seg
Definition: homog2d_test.cpp:4051
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:8209
Line2d li
Definition: homog2d_test.cpp:4053
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4289
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
auto helper_test_seg_intersect(Line2d_< FPT > li, const SEG &seg, bool doesIntersects)
Definition: homog2d_test.cpp:2180
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] 
)
2226 {
2227  INFO( "with diagonal line" )
2228  {
2229  Line2d_<NUMTYPE> li(1,1); // diagonal line going through (0,0)
2230  Point2d_<NUMTYPE> pt1, pt2; // 0,0
2231 
2232  pt2.set(1,1);
2233  auto ri = li.intersects( FRect(pt1, pt2) );
2234  CHECK( ri() == true );
2235  CHECK( ri.size() == 2 );
2236  auto pts = ri.get();
2237  CHECK( pts[0] == pt1 );
2238  CHECK( pts[1] == pt2 );
2239 
2240  pt1.set( 5,0 );
2241  pt2.set( 6,1 );
2242  ri = li.intersects( FRect(pt1, pt2) );
2243  CHECK( ri() == false );
2244  }
2245  INFO( "with H/V line" )
2246  {
2247  Point2d_<NUMTYPE> pt1, pt2(1,1); // rectangle (0,0) - (1,1)
2248  FRect_<NUMTYPE> r1(pt1, pt2);
2249  Line2d_<NUMTYPE> li = Point2d_<NUMTYPE>() * Point2d_<NUMTYPE>(0,1); // vertical line at y=x
2250  auto ri1 = li.intersects( r1 );
2251  auto ri2 = r1.intersects( li );
2252  CHECK( ri1() == true );
2253  CHECK( ri2() == true );
2254 
2255  CHECK( ri1.size() == 2 );
2256  CHECK( ri2.size() == 2 );
2257  auto pts1 = ri1.get();
2258  auto pts2 = ri2.get();
2259  CHECK( pts1[0] == pt1 );
2260  CHECK( pts1[1] == Point2d(0,1) );
2261 
2262  CHECK( pts2[0] == pt1 );
2263  CHECK( pts2[1] == Point2d(0,1) );
2264 
2265  li = Point2d_<NUMTYPE>(1,0) * Point2d_<NUMTYPE>(1,1); // vertical line at x=1
2266  ri1 = li.intersects( r1 );
2267  ri2 = r1.intersects( li );
2268  CHECK( ri1() == true );
2269  CHECK( ri2() == true );
2270  CHECK( ri1.size() == 2 );
2271  CHECK( ri2.size() == 2 );
2272 
2273  pts1 = ri1.get();
2274  CHECK( pts1[0] == Point2d(1,0) );
2275  CHECK( pts1[1] == Point2d(1,1) );
2276 
2277  li = Point2d_<NUMTYPE>() * Point2d_<NUMTYPE>(1,0); // horizontal line at y=0
2278  ri1 = li.intersects( r1 );
2279  ri2 = r1.intersects( li );
2280  CHECK( ri1() == true );
2281  CHECK( ri2() == true );
2282  CHECK( ri1.size() == 2 );
2283  CHECK( ri2.size() == 2 );
2284 
2285  pts1 = ri1.get();
2286  CHECK( pts1[0] == pt1 );
2287  CHECK( pts1[1] == Point2d(1,0) );
2288 
2289  li = Point2d_<NUMTYPE>(-1,1) * Point2d_<NUMTYPE>(1,1); // horizontal line at y=1
2290  ri1 = li.intersects( r1 );
2291  ri2 = r1.intersects( li );
2292  CHECK( ri1() == true );
2293  CHECK( ri2() == true );
2294  CHECK( ri1.size() == 2 );
2295  CHECK( ri2.size() == 2 );
2296 
2297  pts1 = ri1.get();
2298  CHECK( pts1[0] == Point2d(0,1) );
2299  CHECK( pts1[1] == Point2d(1,1) );
2300 
2301  li = Point2d_<NUMTYPE>(-1.,.5) * Point2d_<NUMTYPE>(2.,.5); // horizontal line at y=0.5
2302  ri1 = li.intersects( r1 );
2303  ri2 = r1.intersects( li );
2304  CHECK( ri1() == true );
2305  CHECK( ri2() == true );
2306  CHECK( ri1.size() == 2 );
2307  CHECK( ri2.size() == 2 );
2308 
2309  pts1 = ri1.get();
2310  CHECK( pts1[0] == Point2d(0.,.5) );
2311  CHECK( pts1[1] == Point2d(1.,.5) );
2312  }
2313  INFO( "single point intersection" )
2314  {
2315  FRect_<NUMTYPE> r1( 0,0,1,1 );
2316  Line2d_<NUMTYPE> li( -1,+1, +1,-1 );
2317  auto inter = r1.intersects( li );
2318  CHECK( inter.size() == 1 );
2319  auto pts = inter.get();
2320  CHECK( pts[0] == Point2d(0,0) );
2321  }
2322 }
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
detail::Intersect< detail::Inters_1, FPT > intersects(const Line2d_< FPT2 > &other) const
Line/Line intersection.
Definition: homog2d.hpp:4289
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3892
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] 
)
2330 {
2331  Point2d p00(0,0), p01(0,1), p30(3,0);
2332  Point2d pt1, pt2, pt3;
2333 
2334  {
2335  pt1 = p01; pt2 = p00; pt3 = p30; // case A
2336  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2337  CHECK( arr[0]==pt3 );
2338  CHECK( arr[1]==pt1 );
2339  CHECK( arr[2]==pt2 );
2340  }
2341  {
2342  pt1 = p01; pt2 = p30; pt3 = p00; // case B
2343  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2344  CHECK( arr[0]==pt2 );
2345  CHECK( arr[1]==pt1 );
2346  CHECK( arr[2]==pt3 );
2347  }
2348  {
2349  pt1 = p00; pt2 = p01; pt3 = p30; // case C
2350  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2351  CHECK( arr[0]==pt3 );
2352  CHECK( arr[1]==pt2 );
2353  CHECK( arr[2]==pt1 );
2354  }
2355  {
2356  pt1 = p30; pt2 = p01; pt3 = p00; // case D
2357  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2358  CHECK( arr[0]==pt1 );
2359  CHECK( arr[1]==pt2 );
2360  CHECK( arr[2]==pt3 );
2361  }
2362  {
2363  pt1 = p00; pt2 = p30; pt3 = p01; // case E
2364  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2365  CHECK( arr[0]==pt2 );
2366  CHECK( arr[1]==pt3 );
2367  CHECK( arr[2]==pt1 );
2368  }
2369  {
2370  pt1 = p30; pt2 = p00; pt3 = p01; // case F
2371  auto arr = priv::getLargestDistancePoints( pt1, pt2, pt3 );
2372  CHECK( arr[0]==pt1 );
2373  CHECK( arr[1]==pt3 );
2374  CHECK( arr[2]==pt2 );
2375  }
2376  {
2377  Point2d p1(0,0), p2(1,0), p3(4,0);
2378  CHECK( areCollinear( p1, p2, p3 ) );
2379  }
2380  {
2381  Point2d p1(1,0), p2(0,0), p3(4,0);
2382  CHECK( areCollinear( p1, p2, p3 ) );
2383  }
2384  {
2385  Point2d p1(1,0), p2(0,0), p3(4,1E-3);
2386  CHECK( !areCollinear( p1, p2, p3 ) );
2387  }
2388 }
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:3616
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:3687
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] 
)
2391 {
2393  CHECK( li.area() == 0. );
2394  CHECK_THROWS( li.length() );
2395 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
constexpr HOMOG2D_INUMTYPE area() const
Neither lines nor points have an area.
Definition: homog2d.hpp:4277
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE length() const
A point has a null length, a line has an infinite length.
Definition: homog2d.hpp:4266
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] 
)

?

2398 {
2399  {
2400  Circle_<NUMTYPE> c1; // Default constructor
2401  CHECK( c1.center() == Point2d(0,0) );
2402  CHECK( center(c1) == Point2d(0,0) );
2403  CHECK( c1.radius() == 1. );
2404  CHECK( radius(c1) == 1. );
2405  CHECK( c1.getBB() == FRect(-1,-1,1,1 ) );
2406  CHECK( getBB(c1) == FRect(-1,-1,1,1 ) );
2407 
2408  CHECK( c1.area() == area(c1) );
2409  CHECK( c1.length() == length(c1) );
2410  }
2411  {
2412  int i = 44;
2413  Circle_<NUMTYPE> c1(i); // 1-arg Constructor - radius
2414  CHECK( c1.center() == Point2d(0,0) );
2415  CHECK( c1.radius() == i );
2416  CHECK( c1.getBB() == FRect(-i,-i,i,i) );
2417  CHECK( getBB(c1) == FRect(-i,-i,i,i) );
2418  c1.set( 454 );
2419  CHECK( c1.center() == Point2d(0,0) );
2420  CHECK( c1.radius() == 454 );
2421  }
2422  {
2423  Point2d_<NUMTYPE> pt( 4,5);
2424  Circle_<NUMTYPE> c2(pt); // 1-arg Constructor - center
2425  CHECK( c2.center() == Point2d(4,5) );
2426  CHECK( c2.radius() == 1 );
2427 
2428  CHECK( center(c2) == Point2d(4,5) ); // free functions call
2429  CHECK( radius(c2) == 1 );
2430 
2431  c2.set( Point2d_<NUMTYPE>(18,22) );
2432  CHECK( c2.center() == Point2d(18,22) );
2433  CHECK( c2.radius() == 1 );
2434  }
2435  {
2436  Point2d_<NUMTYPE> pt1(0,0), pt2(4,0);
2437  Circle_<NUMTYPE> c1(pt1,pt2); // 2-args constructor: 2 points
2438  CHECK( c1.center() == Point2d(2,0) );
2439  CHECK( c1.radius() == 2. );
2440  c1.set( Point2d(1,1), Point2d(1,5) );
2441  CHECK( c1.center() == Point2d(1,3) );
2442  CHECK( c1.radius() == 2. );
2443  }
2444  {
2445  Point2d_<NUMTYPE> pt1(4,5);
2446  Circle_<NUMTYPE> c2(pt1,3); // 2-args constructor - center and radius
2447  CHECK( c2.center() == pt1 );
2448  CHECK( c2.radius() == 3 );
2449 
2450  c2.set( Point2d_<NUMTYPE>(42,24), 18 );
2451  CHECK( c2.center() == Point2d_<NUMTYPE>(42,24) );
2452  CHECK( c2.radius() == 18 );
2453  }
2454  {
2455  Circle_<NUMTYPE> c1(1,2,3); // 3-args constructor: x0, y0, radius
2456  CHECK( c1.center() == Point2d(1,2) );
2457  CHECK( c1.radius() == 3 );
2458 
2459  c1.set( 11, 22, 33 );
2460  CHECK( c1.center() == Point2d(11,22) );
2461  CHECK( c1.radius() == 33 );
2462  }
2463  {
2464  CHECK_THROWS( Circle_<NUMTYPE>(1,2,0.) );
2465  CHECK_THROWS( Circle_<NUMTYPE>(1,2,-1.) );
2466  }
2467  {
2468  Point2d_<NUMTYPE> pt1(4,5), pt2(6,7), pt3; // 3-args constructor: 3 points
2469  Circle_<NUMTYPE> c1(pt1,pt2,pt3); // 2-args constructor: 2 points
2470 
2471  c1.set( Point2d(4,5), Point2d(6,7), Point2d(2,2) );
2472 
2473  CHECK_THROWS( c1.set( Point2d(4,5), Point2d(4,5) ) ); // points must be different !
2474  CHECK_THROWS( c1.set( Point2d(4,5), Point2d(4,5), Point2d(2,2) ) );
2475  CHECK_THROWS( Circle( Point2d(4,5), Point2d(4,5), Point2d(2,2) ) );
2476  CHECK_THROWS( Circle( Point2d(4,5), Point2d(4,5) ) );
2477  }
2478  {
2479  Circle_<NUMTYPE> c1;
2480 
2481  CHECK( c1.radius() == 1 );
2482  c1.radius() = 2; // member function call
2483  CHECK( c1.radius() == 2 );
2484  radius(c1) = 3; // free function call
2485  CHECK( radius(c1) == 3 );
2486 
2487  CHECK( center(c1) == Point2d() );
2488  c1.center() = Point2d(3,4); // member function call
2489  CHECK( center(c1) == Point2d(3,4) );
2490  center(c1) = Point2d(5,6); // free function call
2491  CHECK( center(c1) == Point2d(5,6) );
2492  }
2493 }
HOMOG2D_INUMTYPE area() const
Area of circle.
Definition: homog2d.hpp:3307
A circle.
Definition: homog2d.hpp:378
auto getBB() const
Returns Bounding Box of circle.
Definition: homog2d.hpp:3319
Point2d_< FPT > & center(Circle_< FPT > &cir)
Returns reference on center of circle (free function), non-const version.
Definition: homog2d.hpp:10938
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12396
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:10227
HOMOG2D_INUMTYPE length() const
Perimeter of circle.
Definition: homog2d.hpp:3313
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
void set(const Point2d_< PT > &center)
Set circle center point, radius unchanged.
Definition: homog2d.hpp:3335
FPT & radius(Circle_< FPT > &cir)
Returns reference on radius of circle (free function), non-const version.
Definition: homog2d.hpp:10920
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10242
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10316
Point2d_< FPT > & center()
Definition: homog2d.hpp:3297
Point2d pt
Definition: homog2d_test.cpp:4052
FPT & radius()
Definition: homog2d.hpp:3294
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] 
)
2496 {
2497  {
2498  INFO( "circle from 2 pts");
2499  std::vector<Point2d_<NUMTYPE>> pts1{ {0,0}, {2,0} };
2500  std::vector<Point2d_<NUMTYPE>> pts2{ {0,3}, {4,3} };
2501 // check using constructor
2502  Circle_<NUMTYPE> c1(pts1);
2503  CHECK( c1.center() == Point2d(1,0) );
2504  CHECK( c1.radius() == 1. );
2505  Circle_<NUMTYPE> c2(pts2);
2506  CHECK( c2.center() == Point2d(2,3) );
2507  CHECK( c2.radius() == 2. );
2508 // check using "set" function
2509  c1.set(pts2);
2510  CHECK( c1.center() == Point2d(2,3) );
2511  CHECK( c1.radius() == 2. );
2512  c2.set(pts1);
2513  CHECK( c2.center() == Point2d(1,0) );
2514  CHECK( c2.radius() == 1. );
2515  }
2516  {
2517  INFO( "circle from 4 pts");
2518  std::vector<Point2d_<NUMTYPE>> pts1{ {0,4}, {4,0}, {0,-4}, {0,0} };
2519  Circle_<NUMTYPE> c1(pts1);
2520  CHECK( c1.center() == Point2d(0,0) );
2521  CHECK( c1.radius() == 4. );
2522  c1.set(pts1);
2523  CHECK( c1.center() == Point2d(0,0) );
2524  CHECK( c1.radius() == 4. );
2525 
2526  std::vector<Point2d_<NUMTYPE>> pts2{ {0,4} };
2527  CHECK_THROWS( Circle_<NUMTYPE>(pts2) ); // 1 point not allowed
2528  std::vector<Point2d_<NUMTYPE>> pts3;
2529  CHECK_THROWS( Circle_<NUMTYPE>(pts3) ); // 0 points not allowed
2530  }
2531 }
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:12383
CHECK_THROWS(CPolyline(-5, 5u))
Here is the call graph for this function:

◆ TEST_CASE() [49/93]

TEST_CASE ( "Ellipse"  ,
""  [ell1] 
)
2534 {
2535  {
2536  Ellipse_<NUMTYPE> el;
2537  CHECK( el.getCenter() == Point2d(0,0) );
2538  CHECK( getCenter(el) == Point2d(0,0) );
2539  CHECK( el.getMajMin().first == 2.0 );
2540  CHECK( el.getMajMin().second == 1.0 );
2541  CHECK( el.angle() == 0.0 );
2542  CHECK( angle(el) == 0.0 );
2543  CHECK( el.isCircle() == false );
2544  CHECK( isCircle(el) == false );
2545  // CHECK( el.getBB() == Point2d(0,0) );
2546  }
2547  {
2548  Circle c(1,2,3);
2549  Ellipse_<NUMTYPE> el(c);
2550  CHECK( el.getCenter() == Point2d(1,2) );
2551  CHECK( getCenter(el) == Point2d(1,2) );
2552  CHECK( el.getMajMin().first == 3.0 );
2553  CHECK( el.getMajMin().second == 3.0 );
2554  CHECK( el.angle() == 0.0 );
2555  CHECK( angle(el) == 0.0 );
2556  CHECK( el.isCircle() == true );
2557  CHECK( isCircle(el) == true );
2558  }
2559 
2560  {
2561  Ellipse_<NUMTYPE> el(1,2,3.0,3.00001);
2562  CHECK( el.getCenter() == Point2d(1,2) );
2563  CHECK( el.isCircle() == false ); // using default threshold
2564  CHECK( isCircle(el) == false );
2565 
2566  CHECK( el.isCircle(1E-3) == true ); // using arbitrary threshold
2567  CHECK( isCircle(el,1E-3) == true );
2568  }
2569 
2570  {
2571  Ellipse_<NUMTYPE> el(4,5,6,7);
2572  CHECK( el.getCenter() == Point2d(4,5) );
2573  CHECK( el.getMajMin().first == Approx(7.0) );
2574  CHECK( el.getMajMin().second == Approx(6.0) );
2575  CHECK( el.angle() == 0.0 );
2576  CHECK( el.isCircle() == false );
2577  }
2578  {
2579  Ellipse_<NUMTYPE> el(4,5, 6, 7, 1 /*rad.*/ );
2580  CHECK( el.getCenter() == Point2d(4,5) );
2581  CHECK( el.getMajMin().first == Approx(7.0) );
2582  CHECK( el.getMajMin().second == Approx(6.0) );
2583  CHECK( el.angle() == Approx(1.0) );
2584  CHECK( el.isCircle() == false );
2585  }
2586 }
A circle.
Definition: homog2d.hpp:378
Point2d_< FPT > getCenter() const
Returns center of ellipse.
Definition: homog2d.hpp:8585
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:10709
bool isCircle(const Ellipse_< FPT > &ell, HOMOG2D_INUMTYPE thres=1.E-10)
Returns true if ellipse is a circle.
Definition: homog2d.hpp:11060
std::pair< HOMOG2D_INUMTYPE, HOMOG2D_INUMTYPE > getMajMin() const
Definition: homog2d.hpp:8594
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:10997
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
bool isCircle(HOMOG2D_INUMTYPE thres=1.E-10) const
Returns true if ellipse is a circle.
Definition: homog2d.hpp:8568
HOMOG2D_INUMTYPE angle() const
Returns angle of ellipse.
Definition: homog2d.hpp:8605
Here is the call graph for this function:

◆ TEST_CASE() [50/93]

TEST_CASE ( "OSegment point side"  ,
""  [oseg-pt-side] 
)
2598 {
2599  OSegment_<NUMTYPE> s1( 0,0,10,0);
2601  CHECK( s1.getPointSide(pt) == PointSide::Neither );
2602  pt.translate(1,1);
2603  CHECK( s1.getPointSide(pt) == PointSide::Left );
2604  pt.translate(0,-5);
2605  CHECK( s1.getPointSide(pt) == PointSide::Right );
2606 
2607  pt.set(0,0);
2608  s1.set( 1,0, 1,10 );
2609  CHECK( s1.getPointSide(pt) == PointSide::Left );
2610 }
void translate(T1 dx, T2 dy)
Translate Point2d, does nothing for Line2d.
Definition: homog2d.hpp:4146
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3892
A line segment, oriented (OSegment_) or not (Segment_). Holds the two points.
Definition: homog2d.hpp:366
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
2613 {
2614  { // test order of points
2615  Point2d p1(43,8);
2616  Point2d p2(43,18);
2617  Point2d p3(5,55);
2618  {
2619  Segment_<NUMTYPE> s( p1, p2 ); // same x value
2620  CHECK( s.getPts().first == p1 );
2621  CHECK( s.getPts().second == p2 );
2622 
2623  s.translate( 2, 3 );
2624  CHECK( s.getPts().first == Point2d(45,11) );
2625  CHECK( s.getPts().second == Point2d(45,21) );
2626 
2627  translate( s, -2, -3 );
2628  CHECK( s.getPts().first == Point2d(43,8) );
2629  CHECK( s.getPts().second == Point2d(43,18) );
2630  }
2631  {
2632  Segment_<NUMTYPE> s( p2, p1 ); // same x value
2633  CHECK( s.getPts().first == p1 );
2634  CHECK( s.getPts().second == p2 );
2635  }
2636  {
2637  Segment_<NUMTYPE> s( p1, p3 );
2638  CHECK( s.getPts().first == p3 );
2639  CHECK( s.getPts().second == p1 );
2640  }
2641  {
2642  Segment_<NUMTYPE> s( p3, p1 );
2643  CHECK( s.getPts().first == p3 );
2644  CHECK( s.getPts().second == p1 );
2645  }
2646  }
2647  {
2648  Point2d_<NUMTYPE> p1( 4,5 );
2649  Point2d_<NUMTYPE> p2( 1,2 );
2650  auto ppts = std::make_pair( p1, p2 );
2651  Segment_<NUMTYPE> s( ppts );
2652  CHECK( s.getPts().first == p2 );
2653  CHECK( s.getPts().second == p1 );
2654  s.set( ppts );
2655  }
2656  {
2657  Line2d_<NUMTYPE> li( Point2d(0,0), Point2d(2,2) );
2658  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2659  Segment_<NUMTYPE> s2( Point2d(2,2), Point2d(0,0) );
2660  CHECK( s1 == s2 );
2661  CHECK( s1.isParallelTo(s2) );
2662  Line2d_<NUMTYPE> l1( Point2d(10,0), Point2d(12,2) );
2663  CHECK( s1.isParallelTo(l1) );
2664  CHECK( l1.isParallelTo(s1) );
2665  CHECK( l1.getAngle( s1 ) == Approx(0) );
2666  CHECK( s1.getAngle( l1 ) == Approx(0) );
2667  CHECK( s1.getAngle( s2 ) == Approx(0) );
2668  CHECK( getAngle( s1, s2 ) == Approx(0) );
2669  CHECK( getAngle( li, s2 ) == Approx(0) );
2670  CHECK( getAngle( s2, li ) == Approx(0) );
2671  }
2672  {
2673  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(3,4) );
2674  CHECK( s1.length() == 5 );
2675  CHECK( s1.area() == 0 );
2676 
2677  Segment_<NUMTYPE> s2( Point2d(9,9), Point2d(8,8) );
2678  auto pts = s2.getPts();
2679  CHECK( pts.first == Point2d_<NUMTYPE>(8,8) );
2680  CHECK( pts.second == Point2d_<NUMTYPE>(9,9) );
2681  }
2682  {
2683  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2684  Segment_<NUMTYPE> s2( Point2d(2,0), Point2d(0,2) );
2685  auto si = s1.intersects(s2);
2686  CHECK( si() == true );
2687  CHECK( si.get() == Point2d_<NUMTYPE>(1,1) );
2688 
2689  auto pt = s1.getCenter();
2690  CHECK( pt == Point2d_<NUMTYPE>(1,1) );
2691  }
2692  {
2693  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(2,2) );
2694  Segment_<NUMTYPE> s2( Point2d(2,0), Point2d(0,2) );
2695  auto bis = s1.getBisector();
2696  CHECK( bis == s2.getLine() );
2697  }
2698  { // test that points on a line at equal distance from a point, when
2699  // transformed in a segment, we get back as middle point the same one.
2700  Line2d li(9,9); // diagonal line (0,0) - (9,9)
2701  auto ppts = li.getPoints( GivenCoord::X, 5, 1 );
2702  Segment_<NUMTYPE> s1( ppts.first, ppts.second );
2703  CHECK( s1.getCenter() == Point2d_<NUMTYPE>(5,5) );
2704  }
2705 }
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:4089
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9208
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Line2d li
Definition: homog2d_test.cpp:4053
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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:11019
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
2708 {
2709  INFO( "Translate Circle" );
2710  Circle_<NUMTYPE> c(5,5,10);
2711  c.translate(-1,+1);
2712  CHECK( c.center() == Point2d(4,6) );
2713  translate( c, +1, -1 );
2714  CHECK( c.center() == Point2d(5,5) );
2715 
2716  translate( c, std::make_pair(2,3) );
2717  CHECK( c.center() == Point2d(7,8) );
2718  c.translate( std::make_pair(-2,-3) );
2719  CHECK( c.center() == Point2d(5,5) );
2720 
2721  INFO( "Translate Point" );
2722  Point2d_<NUMTYPE> pt(4,5);
2723  pt.translate(-1,+1);
2724  CHECK( pt == Point2d(3,6) );
2725  translate(pt,+1,-1);
2726  CHECK( pt == Point2d(4,5) );
2727 
2728  translate( pt, std::make_pair(2,3) );
2729  CHECK( pt == Point2d(6,8) );
2730  pt.translate( std::make_pair(-2,-3) );
2731  CHECK( pt == Point2d(4,5) );
2732 }
A circle.
Definition: homog2d.hpp:378
void translate(T1 dx, T2 dy)
Translate Point2d, does nothing for Line2d.
Definition: homog2d.hpp:4146
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
void translate(T &prim, FP1 dx, FP2 dy)
Translate primitive prim (free function)
Definition: homog2d.hpp:11019
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
2735 {
2736  INFO( "MoveTo Circle" );
2737  Circle_<NUMTYPE> c(5,5,10);
2738  c.moveTo( 9,8 );
2739  CHECK( c.center() == Point2d(9,8) );
2740  moveTo(c,8,9);
2741  CHECK( c.center() == Point2d(8,9) );
2742 
2743  Point2d_<NUMTYPE> pt1(1,1);
2744  moveTo(c,pt1);
2745  CHECK( c.center() == pt1 );
2746  Point2d_<NUMTYPE> pt2(3,3);
2747  c.moveTo(pt2);
2748  CHECK( c.center() == pt2 );
2749 
2750 // INFO( "MoveTo Segment" );
2751 
2752 
2753 }
A circle.
Definition: homog2d.hpp:378
void moveTo(T &prim, const Point2d_< FP > &pt)
Move primitive to other location (free function)
Definition: homog2d.hpp:11041
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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] 
)
2756 {
2757  Segment_<NUMTYPE> s1( Point2d(0,0), Point2d(20,0) );
2758  OSegment_<NUMTYPE> s2( Point2d(0,0), Point2d(20,0) );
2759  {
2760  auto psegs1 = s1.split();
2761  auto psegs2 = split(s1);
2762  CHECK( psegs1 == psegs2 );
2763  CHECK( psegs1.first == Segment_<NUMTYPE>( Point2d(0,0), Point2d(10,0) ) );
2764  CHECK( psegs1.second == Segment_<NUMTYPE>( Point2d(10,0), Point2d(20,0) ) );
2765  }
2766  {
2767  auto psegs1 = s2.split();
2768  auto psegs2 = split(s2);
2769  CHECK( psegs1 == psegs2 );
2770  CHECK( psegs1.first == OSegment_<NUMTYPE>( Point2d(0,0), Point2d(10,0) ) );
2771  CHECK( psegs1.second == OSegment_<NUMTYPE>( Point2d(10,0), Point2d(20,0) ) );
2772  }
2773 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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:10653
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] 
)
2776 {
2777  OSegment_<NUMTYPE> s1( Point2d(0,0), Point2d(20,0) );
2778 
2779  CHECK_THROWS( s1.split(-4) );
2780  CHECK_THROWS( s1.split(0) );
2781  CHECK_THROWS( s1.split(20) );
2782 
2783  CHECK_THROWS( split(s1,-4) );
2784  CHECK_THROWS( split(s1,0) );
2785  CHECK_THROWS( split(s1,20) );
2786 
2787  auto psegs1 = s1.split(4);
2788  auto psegs2 = split(s1,4);
2789  CHECK( psegs1 == psegs2 );
2790  CHECK( psegs1.first == OSegment_<NUMTYPE>( Point2d(0,0), Point2d(4,0) ) );
2791  CHECK( psegs1.second == OSegment_<NUMTYPE>( Point2d(4,0), Point2d(20,0) ) );
2792 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
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:10653
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] 
)
2795 {
2796  {
2797  Segment_<HOMOG2D_INUMTYPE> seg (0,0,1,0); // horizontal segment
2798  auto psegs = seg.getParallelSegs(1.);
2799  auto psegs2 = seg.getParallelSegs(1.);
2800  CHECK( psegs == psegs2 );
2801  CHECK( psegs.first == Segment(0,-1,1,-1) );
2802  CHECK( psegs.second == Segment(0,+1,1,+1) );
2803  }
2804  {
2805  Segment_<HOMOG2D_INUMTYPE> seg (0,0,0,1); // vertical segment
2806  auto psegs = seg.getParallelSegs(1.);
2807  CHECK( psegs.first == Segment(-1,0,-1,+1) );
2808  CHECK( psegs.second == Segment(+1,0,+1,+1) );
2809  }
2810 }
Segment seg
Definition: homog2d_test.cpp:4051
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] 
)
2813 {
2815  auto s2 = seg.getExtended();
2816  CHECK( s2.length() == 3. );
2817  CHECK( s2.getPts().first == Point2d(-1,0) );
2818  CHECK( s2.getPts().second == Point2d(2,0) );
2819 
2820  auto s3 = getExtended(seg);
2821  CHECK( s3.length() == 3. );
2822  CHECK( s3.getPts().first == Point2d(-1,0) );
2823  CHECK( s3.getPts().second == Point2d(2,0) );
2824 }
Segment_< FPT > getExtended(const Segment_< FPT > &seg)
Returns Extended Segment (free function)
Definition: homog2d.hpp:10644
Segment seg
Definition: homog2d_test.cpp:4051
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
SegVec< SV, FPT > getExtended() const
Returns a segment with same support line but tripled length.
Definition: homog2d.hpp:5480
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] 
)
2827 {
2829  auto pts = seg.getOrthogPts();
2830  auto pts2 = getOrthogPts(seg);
2831  CHECK( pts2 == pts );
2832  auto pol = CPolyline(pts);
2833  CHECK( pol == CPolyline( std::vector<Point2d>{ {0,-1},{1,-1},{1,1},{0,1} } ) );
2834 
2835  auto osegs = seg.getOrthogSegs();
2836  auto osegs2 = getOrthogSegs(seg);
2837  CHECK( osegs2 == osegs );
2838  std::array<Segment_<HOMOG2D_INUMTYPE>,4> gt;
2839  gt[0] = Segment( 0,0,0,+1 );
2840  gt[1] = Segment( 0,0,0,-1 );
2841  gt[2] = Segment( 1,0,1,+1 );
2842  gt[3] = Segment( 1,0,1,-1 );
2843  std::sort( gt.begin(), gt.end() );
2844  std::sort( osegs.begin(), osegs.end() );
2845  CHECK( gt == osegs );
2846 }
Segment seg
Definition: homog2d_test.cpp:4051
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
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:10683
std::array< Segment_< FPT >, 4 > getOrthogSegs() const
Returns the 4 segments/vectors orthogonal to the segment.
Definition: homog2d.hpp:5243
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12402
std::array< Segment_< FPT >, 4 > getOrthogSegs(const Segment_< FPT > &seg)
Returns the 4 orthogonal segments to the segment.
Definition: homog2d.hpp:10674
std::array< Point2d_< FPT >, 4 > getOrthogPts() const
Returns the 4 points orthogonal to the segment/vector.
Definition: homog2d.hpp:5236
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] 
)
2849 {
2850  Point2d_<NUMTYPE> pt0(0,0), pt1(1,1), pt2(2,2), pt3(3,3);
2851  auto pp1 = std::make_pair( pt0,pt1 );
2852  auto pp2 = std::make_pair( pt2,pt3 );
2853  auto ppts = getMinMax( pp1, pp2 );
2854  CHECK( ppts.first == Point2d_<NUMTYPE>(0,0) );
2855  CHECK( ppts.second == Point2d_<NUMTYPE>(3,3) );
2856 // TODO: EXTEND
2857 }
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:10402
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] 
)
2861 {
2862  Point2d_<NUMTYPE> pt,pt2(1,1);
2863  FRect_<NUMTYPE> re,re2;
2864  Segment_<NUMTYPE> se,se2(1,0,0,1);
2865  CPolyline_<NUMTYPE> pc,pc2;
2866  OPolyline_<NUMTYPE> po,po2;
2867  Ellipse_<NUMTYPE> el,el2;
2868 
2869  CHECK( getBB(pt,pt2) == FRect_<NUMTYPE>() ); // (0,0) - (1,1)
2870  CHECK( getBB(se,se2) == FRect_<NUMTYPE>() ); // [(0,0) - (1,1)] - [(1,0) - (0,1)]
2871  CHECK( getBB(se,se) == FRect_<NUMTYPE>() ); // identical segments, but they cover some area
2872  CHECK( getBB(re,re2) == FRect_<NUMTYPE>() );
2873  CHECK( getBB(se,se2) == FRect_<NUMTYPE>() );
2874  CHECK( getBB(el,el2) == getBB(el) ); // identical
2875 
2876  CHECK_THROWS( getBB(pc,pc2) ); // empty
2877  CHECK_THROWS( getBB(pt,pt) ); // identical points => no BB
2878 
2879  pt2.set(0,1);
2880  CHECK_THROWS( getBB(pt,pt2) ); // one of the coordinates is identical
2881 
2882  se.set( 0,0,1,0 );
2883  se2.set( 10,0,11,0 );
2884  CHECK_THROWS( getBB(se,se) ); // segments are colinear
2885  CHECK_THROWS( getBB(se,se2) ); // segments are colinear
2886 
2887  pt2.set(0,0);
2888  CHECK_THROWS( getBB(se,pt2) ); // no area
2889 
2890  pc.set( std::vector<Point2d_<NUMTYPE>>{ {0,0},{1,0} } );
2891  CHECK_THROWS( getBB(pc) ); // no area
2892  CHECK_THROWS( getBB(pc, pc2) ); // no area, and second is empty
2893 
2894  pc2.set( std::vector<Point2d_<NUMTYPE>>{ {5,0},{6,0} } );
2895  CHECK_THROWS( getBB(pc,pc2) ); // colinear
2896 
2897  pc2.set( std::vector<Point2d_<NUMTYPE>>{ {5,1},{6,1} } );
2898  CHECK( getBB(pc,pc2) == FRect_<NUMTYPE>(0,0,6,1) );
2899 }
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:6465
CHECK_THROWS(CPolyline(-5, 5u))
void set(const Point2d_< FP1 > &p1, const Point2d_< FP2 > &p2)
Setter.
Definition: homog2d.hpp:4964
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:10316
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
2903 {
2904  {
2905  std::vector<Point2d_<NUMTYPE>> vec(3);
2906  vec[0] = Point2d_<NUMTYPE>(1,1);
2907  vec[1] = Point2d_<NUMTYPE>(5,6);
2908  vec[2] = Point2d_<NUMTYPE>(3,2);
2909  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2910  }
2911  {
2912  std::array<Point2d_<NUMTYPE>,3> vec;
2913  vec[0] = Point2d_<NUMTYPE>(1,1);
2914  vec[1] = Point2d_<NUMTYPE>(5,6);
2915  vec[2] = Point2d_<NUMTYPE>(3,2);
2916  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2917  }
2918  {
2919  std::list<Point2d_<NUMTYPE>> vec;
2920  vec.emplace_back( Point2d_<NUMTYPE>(1,1) );
2921  vec.emplace_back( Point2d_<NUMTYPE>(5,6) );
2922  vec.emplace_back( Point2d_<NUMTYPE>(3,2) );
2923  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,5,6) );
2924  }
2925  {
2926  std::vector<Line2d_<NUMTYPE>> vec(3); // cannot get BB of a set of lines
2927  CHECK_THROWS( getBB(vec) );
2928  }
2929  {
2930  std::vector<FRect_<NUMTYPE>> vec(3);
2931  vec[0] = FRect_<NUMTYPE>(1,1,2,2);
2932  vec[1] = FRect_<NUMTYPE>(5,6,10,11);
2933  vec[2] = FRect_<NUMTYPE>(3,2,4,5);
2934  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,10,11) );
2935  }
2936  {
2937  std::vector<Segment_<NUMTYPE>> vec(3);
2938  vec[0] = Segment_<NUMTYPE>(1,1,2,2);
2939  vec[1] = Segment_<NUMTYPE>(5,6,10,11);
2940  vec[2] = Segment_<NUMTYPE>(3,2,4,5);
2941  CHECK( getBB(vec) == FRect_<NUMTYPE>(1,1,10,11) );
2942  }
2943  {
2944  std::vector<Circle_<NUMTYPE>> vec(3);
2945  vec[0] = Circle_<NUMTYPE>(1,1,1);
2946  vec[1] = Circle_<NUMTYPE>(5,3,2);
2947  vec[2] = Circle_<NUMTYPE>(10,11,2);
2948  CHECK( getBB(vec) == FRect_<NUMTYPE>(0,0,12,13) );
2949  }
2950 #ifdef HOMOG2D_ENABLE_VRTP
2951  {
2952  std::vector<CommonType_<NUMTYPE>> vec(4);
2953  vec[0] = Circle_<NUMTYPE>(3,4,1);
2954  vec[1] = Segment_<NUMTYPE>(5,3,2,8);
2955  vec[2] = FRect_<NUMTYPE>(10,11,2,2);
2956  vec[3] = Line2d_<NUMTYPE>();
2957  CHECK( getBB(vec) == FRect_<NUMTYPE>(10,11,2,2) );
2958  }
2959 #endif
2960 }
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:10316
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] 
)
2963 {
2965  FRect_<NUMTYPE> r1;
2966  CHECK( getBB( pt, r1 ) == r1 );
2967  CHECK( getBB( r1, pt ) == r1 );
2968  Segment_<NUMTYPE> seg( 0,0,1,1);
2969  CHECK( getBB( seg, pt ) == r1 );
2970  CHECK( getBB( pt, seg ) == r1 );
2971 
2973  pt.set( 10,0);
2974  CHECK( getBB( pt, cir ) == FRect_<NUMTYPE>(-1.,-1.,+10.,+1. ) );
2975 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4051
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
void set(T0 v0, T1 v1, T2 v2)
Assign homogeneous values.
Definition: homog2d.hpp:3892
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:10316
Point2d pt
Definition: homog2d_test.cpp:4052
Circle cir
Definition: homog2d_test.cpp:4054
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] 
)
2978 {
2979  { // two identical rectangles
2980  FRect_<NUMTYPE> r1, r2;
2981  CHECK( getBB(r1,r2) == r1 );
2982  }
2983  { // one bottom left, the other top right
2984  FRect_<NUMTYPE> r1(0,0, 1,1);
2985  FRect_<NUMTYPE> r2(2,2, 4,4);
2986  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,4,4) );
2987  }
2988  { // one top left, the other bottom right
2989  FRect_<NUMTYPE> r1(0,2, 1,3);
2990  FRect_<NUMTYPE> r2(2,0, 4,1);
2991  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,4,3) );
2992  }
2993  { // one inside the other
2994  FRect_<NUMTYPE> r1(0,0, 5,5);
2995  FRect_<NUMTYPE> r2(1,1, 3,3);
2996  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,5,5) );
2997  }
2998  { // one inside the other, with a common edge
2999  FRect_<NUMTYPE> r1(0,0, 5,5);
3000  FRect_<NUMTYPE> r2(1,0, 3,3);
3001  CHECK( getBB(r1,r2) == FRect_<NUMTYPE>(0,0,5,5) );
3002  }
3003 
3004 // test for rectangle of different types
3005  { // one inside the other, with a common edge
3006  FRect_<float> r1(0,0, 5,5);
3007  FRect_<double> r2(1,0, 3,3);
3008  auto bb = getBB(r1,r2);
3009  CHECK( bb == FRect_<long double>(0,0,5,5) );
3010  CHECK( bb.dtype() == Dtype::Float );
3011  }
3012 }
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:10316
Here is the call graph for this function:

◆ TEST_CASE() [64/93]

TEST_CASE ( "bounding box of two objects"  ,
""  [getBB-pair] 
)
3015 {
3016  FRect_<NUMTYPE> r1(0,3, 2,0);
3017  FRect_<NUMTYPE> r2(4,5, 6,8);
3018  FRect_<NUMTYPE> bbr(0,0, 6,8);
3019  CHECK( bbr == getBB( r1,r2 ) );
3020  { // distant segments
3021  Segment_<NUMTYPE> s1(0,3, 2,0);
3022  Segment_<NUMTYPE> s2(4,5, 6,8);
3023  FRect_<NUMTYPE> bbs(0,0, 6,8);
3024  CHECK( bbs == getBB( s1,s2 ) );
3025  }
3026  { // crossing segments
3027  Segment_<NUMTYPE> s1(0,0, 5,5);
3028  Segment_<NUMTYPE> s2(0,6, 4,0);
3029  FRect_<NUMTYPE> bbs(0,0, 5,6);
3030  CHECK( bbs == getBB( s1,s2 ) );
3031  }
3032 
3033  { // one circle inside the other
3034  Circle_<NUMTYPE> c1(0,0, 2);
3035  Circle_<NUMTYPE> c2(0,1, 4);
3036  FRect_<NUMTYPE> bbc(-4,-3, +4,5);
3037  CHECK( bbc == getBB( c1,c2 ) );
3038  }
3039  { // two distant circles
3040  Circle_<NUMTYPE> c1(5,5, 2);
3041  Circle_<NUMTYPE> c2(0,0, 1);
3042  FRect_<NUMTYPE> bbc(-1,-1, 7,7);
3043  CHECK( bbc == getBB( c1,c2 ) );
3044  }
3045  { // CPolyline / Frect
3046  CPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3048  CHECK( getBB(po,rect) == FRect_<NUMTYPE>(0,0,3,2) );
3049  }
3050  { // OPolyline / Frect
3051  OPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3053  CHECK( getBB(po,rect) == FRect_<NUMTYPE>(0,0,3,2) );
3054  }
3055  { // OPolyline / Segment
3056  OPolyline_<NUMTYPE> po( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3057  Segment_<NUMTYPE> seg; // [0,0]-[1,1]
3058  CHECK( getBB(seg,po) == FRect_<NUMTYPE>(0,0,3,2) );
3059  }
3060  { // 2 CPolyline, one is empty
3061  CPolyline_<NUMTYPE> po1( std::vector<Point2d>{ {0,0}, {1,1}, {3,2} } );
3062  CPolyline_<NUMTYPE> po2;
3063  CHECK( getBB(po1,po2) == getBB(po1) );
3064  }
3065  { // Circle / Frect
3066  Circle_<NUMTYPE> cir( 5,5,3 ); // center at 5,5, radius=3
3067  FRect_<NUMTYPE> rect; // (0,0)--(1,1)
3068  CHECK( getBB(cir,rect) == FRect_<NUMTYPE>(0,0,8,8) );
3069  }
3070  { // Circle / Segment
3071  Circle_<NUMTYPE> cir( 5,5,3 ); // center at 5,5, radius=3
3072  Segment_<NUMTYPE> seg(10,20,30,40);
3073  CHECK( getBB(cir,seg) == FRect_<NUMTYPE>(2,2,30,40) );
3074  }
3075  { // Circle / Circle (one inside the other)
3076  Circle_<NUMTYPE> cir1( 5,5,3 ); // center at 5,5, radius=3
3077  Circle_<NUMTYPE> cir2( 5,5,1 ); // center at 5,5, radius=1
3078  CHECK( getBB(cir1,cir2) == FRect_<NUMTYPE>(2,2,8,8) );
3079  }
3080  { // two identical Circles
3081  Circle_<NUMTYPE> cir1,cir2;
3082  CHECK( getBB(cir1,cir2) == FRect_<NUMTYPE>(-1,-1,1,1) );
3083  }
3084  { // two identical Ellipses
3085  Ellipse_<NUMTYPE> e1,e2;
3086  CHECK( getBB(e1,e2) == FRect_<NUMTYPE>(-2,-1,2,1) );
3087  }
3088 }
A circle.
Definition: homog2d.hpp:378
Segment seg
Definition: homog2d_test.cpp:4051
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
FRect rect
Definition: homog2d_test.cpp:4056
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:10316
Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.
Definition: homog2d.hpp:364
Circle cir
Definition: homog2d_test.cpp:4054
Here is the call graph for this function:

◆ TEST_CASE() [65/93]

TEST_CASE ( "FRect"  ,
""  [frect] 
)
3091 {
3092  {
3093  FRect_<NUMTYPE> r1;
3094  CHECK( r1.width() == 1. );
3095  CHECK( r1.height() == 1. );
3096  CHECK( r1.length() == 4 );
3097  CHECK( r1.area() == 1 );
3098  CHECK( r1.getCenter() == Point2d(0.5,0.5) );
3099 
3100 // free functions
3101  CHECK( width(r1) == 1. );
3102  CHECK( height(r1) == 1. );
3103  CHECK( length(r1) == 4 );
3104  CHECK( area(r1) == 1 );
3105  CHECK( getCenter(r1) == Point2d(0.5,0.5) );
3106 
3107  auto p_pts = r1.getPts();
3108  CHECK( p_pts.first == Point2d() );
3109  CHECK( p_pts.second == Point2d(1.,1.) );
3110 
3111  auto pts = r1.get4Pts();
3112  CHECK( pts[0] == Point2d(0,0) );
3113  CHECK( pts[1] == Point2d(0,1) );
3114  CHECK( pts[2] == Point2d(1,1) );
3115  CHECK( pts[3] == Point2d(1,0) );
3116  }
3117  CHECK_THROWS( FRect_<NUMTYPE>( Point2d(4,5), Point2d(4,2) ) );
3118  {
3119  FRect_<NUMTYPE> r2a( Point2d(6,5), Point2d(1,2) );
3120  FRect_<NUMTYPE> r2b( Point2d(6,2), Point2d(1,5) );
3121  CHECK( r2a == r2b );
3122 
3123  CHECK( r2a.width() == 5. );
3124  CHECK( r2a.height() == 3. );
3125  auto p_pts = r2b.getPts();
3126  CHECK( p_pts.first == Point2d(1,2) );
3127  CHECK( p_pts.second == Point2d(6,5) );
3128 
3129  auto pts = r2b.get4Pts();
3130  CHECK( pts[0] == Point2d(1,2) );
3131  CHECK( pts[1] == Point2d(1,5) );
3132  CHECK( pts[2] == Point2d(6,5) );
3133  CHECK( pts[3] == Point2d(6,2) );
3134  }
3135  {
3136  FRect_<NUMTYPE> r;
3137  auto s = r.getSegs();
3138  auto s2 = getSegs( r );
3139  CHECK( s == s2 );
3140  CHECK( s[0] == Segment(0,0, 0,1) );
3141  CHECK( s[1] == Segment(0,1, 1,1) );
3142  CHECK( s[2] == Segment(1,1, 1,0) );
3143  CHECK( s[3] == Segment(1,0, 0,0) );
3144  }
3145  {
3146  FRect_<NUMTYPE> r( Point2d(0,0), 100, 50 );
3147  CHECK( r.width() == 100 );
3148  CHECK( r.height() == 50 );
3149  CHECK( r.length() == 300 );
3150  CHECK( r.area() == 5000 );
3151  CHECK( r.getCenter() == Point2d(0,0) );
3152  }
3153  {
3154  FRect_<NUMTYPE> r1( 0,0, 5, 3 );
3155  FRect_<NUMTYPE> r2( 2,3, 7, 6 );
3156  CHECK( r1.size() == r2.size() );
3157  CHECK( size(r1) == size(r2) );
3158  }
3159 }
Point2d_< FPT > getCenter() const
Returns center of rectangle.
Definition: homog2d.hpp:2808
HOMOG2D_INUMTYPE height(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10878
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:2945
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
HOMOG2D_INUMTYPE width(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10886
HOMOG2D_INUMTYPE length(const T &elem)
Returns length of element or variant (free function)
Definition: homog2d.hpp:10227
HOMOG2D_INUMTYPE area() const
Definition: homog2d.hpp:2782
Point2d_< FPT > getCenter(const Segment_< FPT > &seg)
Free function, returns middle point of segment.
Definition: homog2d.hpp:10709
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE length() const
Definition: homog2d.hpp:2783
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10257
constexpr size_t size() const
Definition: homog2d.hpp:2785
std::vector< Segment_< FPT > > getSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the segments of the polyline (free function)
Definition: homog2d.hpp:9941
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:2969
HOMOG2D_INUMTYPE width() const
Definition: homog2d.hpp:2781
HOMOG2D_INUMTYPE height() const
Definition: homog2d.hpp:2780
HOMOG2D_INUMTYPE area(const T &elem)
Returns area of element or variant (free function)
Definition: homog2d.hpp:10242
PointPair_< FPT > getPts() const
Returns the 2 major points of the rectangle.
Definition: homog2d.hpp:2802
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] 
)
3162 {
3164  auto r1a = rect.getExtended();
3165  auto r1b = getExtended(rect);
3166  CHECK( r1a == r1b );
3167  CHECK( r1a == FRect(-1,-1,2,2 ) );
3168  CHECK( r1a.area() == 9 * rect.area() );
3169 
3170  FRect_<NUMTYPE> rect2(4,5,6,6);
3171  CHECK( rect2.getExtended() == FRect(2,4,8,7) );
3172 }
Segment_< FPT > getExtended(const Segment_< FPT > &seg)
Returns Extended Segment (free function)
Definition: homog2d.hpp:10644
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
FRect_< FPT > getExtended() const
Definition: homog2d.hpp:2887
FRect rect
Definition: homog2d_test.cpp:4056
HOMOG2D_INUMTYPE area() const
Definition: homog2d.hpp:2782
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] 
)
3175 {
3176  FRect_<NUMTYPE> r1;
3177  auto psegs1 = r1.getDiagonals();
3178  auto psegs2 = getDiagonals(r1);
3179  CHECK( psegs1 == psegs2 );
3180 
3181  CHECK( psegs1.first == Segment(0,0,1,1) );
3182  CHECK( psegs1.second == Segment(0,1,1,0) );
3183 }
std::pair< Segment_< FPT >, Segment_< FPT > > getDiagonals(const FRect_< FPT > &rect)
Free function.
Definition: homog2d.hpp:10902
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
std::pair< Segment_< FPT >, Segment_< FPT > > getDiagonals() const
Definition: homog2d.hpp:2899
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] 
)
3186 {
3187  std::vector<Point2d_<NUMTYPE>> vpt1{ {0,0}, {1,0}, {1,1} };
3188  std::vector<Point2d_<NUMTYPE>> vpt2{ {1,0}, {1,1}, {0,0} };
3189  {
3190  OPolyline opl1, opl2;
3191  opl1.set( vpt1 );
3192  opl2.set( vpt2 );
3193  CHECK( opl1 != opl2 );
3194 
3195  CPolyline cpl1, cpl2;
3196  cpl1.set( vpt1 );
3197  cpl2.set( vpt2 );
3198  CHECK( cpl1 == cpl2 );
3199 
3200  CHECK( opl1 != cpl1 ); // comparing polygons of different types is allowed
3201  CHECK( opl2 != cpl1 ); // (but will always return false)
3202  }
3203 }
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:6465
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] 
)
3207 {
3208  INFO( "Polyline pl2( IsClosed::No" );
3209  {
3210 #include "figures_test/polyline_min_1O.code" // open
3211 
3212  CHECK( pl.size() == 3 );
3213  CHECK( pl.nbSegs() == 2 );
3214  pl.minimize();
3215  CHECK( pl.size() == 2 );
3216  CHECK( pl.nbSegs() == 1 );
3217  }
3218  {
3219 #include "figures_test/polyline_min_1C.code" // closed
3220  CHECK( pl.size() == 3 );
3221  CHECK( pl.nbSegs() == 3 );
3222  pl.minimize();
3223  CHECK( pl.size() == 2 );
3224  CHECK( pl.nbSegs() == 2 );
3225  }
3226  {
3227 #include "figures_test/polyline_min_2O.code"// open
3228  CHECK( pl.size() == 3 );
3229  CHECK( pl.nbSegs() == 2 );
3230  pl.minimize();
3231 // std::cout << "pl:" << pl << '\n';
3232  CHECK( pl.size() == 3 ); // no change
3233  CHECK( pl.nbSegs() == 2 );
3234  }
3235  {
3236 #include "figures_test/polyline_min_2C.code" // closed
3237  CHECK( pl.size() == 3 );
3238  CHECK( pl.nbSegs() == 3 );
3239  pl.minimize();
3240  CHECK( pl.size() == 3 ); // no change !
3241  CHECK( pl.nbSegs() == 3 );
3242  }
3243  {
3244 #include "figures_test/polyline_min_3O.code" // open
3245  CHECK( pl.size() == 4 );
3246  CHECK( pl.nbSegs() == 3 );
3247  pl.minimize();
3248 // std::cout << "pl:" << pl << '\n';
3249  CHECK( pl.size() == 4 ); // no change
3250  CHECK( pl.nbSegs() == 3 );
3251  }
3252  {
3253 #include "figures_test/polyline_min_3C.code" // closed
3254  CHECK( pl.size() == 4 );
3255  CHECK( pl.nbSegs() == 4 );
3256  pl.minimize();
3257 // std::cout << "pl:" << pl << '\n';
3258  CHECK( pl.size() == 3 ); // no change
3259  CHECK( pl.nbSegs() == 3 );
3260  }
3261 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Here is the call graph for this function:

◆ TEST_CASE() [70/93]

TEST_CASE ( "Polyline"  ,
""  [polyline] 
)
3286 {
3287  { // default constructor
3288  OPolyline_<NUMTYPE> pl1;
3289  polytest_1( pl1 );
3290  CPolyline_<NUMTYPE> pl2;
3291  polytest_1( pl2 );
3292  }
3293  {
3294  CPolyline_<NUMTYPE> pc1;
3295  OPolyline_<NUMTYPE> po1;
3296  std::vector<Point2d> vpt{ {0,0} };
3297  CHECK_THROWS( pc1.set( vpt ) ); // can't hold only 1 point
3298  CHECK_THROWS( po1.set( vpt ) );
3299  }
3300  {
3301  std::vector<Point2d> vpt{ {0,0} };
3302  CHECK_THROWS( CPolyline_<NUMTYPE>( vpt ) ); // can(t build a polyline with a vector of size=1
3304  }
3305  { // build from Rectangle
3306  FRect r( 5,6, 7,8 );
3307  CPolyline_<NUMTYPE> pl1( r );
3308 
3309  CHECK( pl1.isSimple() == true );
3310  CHECK( isSimple(pl1) == true );
3311  CHECK( pl1.size() == 4 );
3312  CHECK( size(pl1) == 4 );
3313  CHECK( pl1.nbSegs() == 4 );
3314  CHECK( nbSegs(pl1) == 4 );
3315  CHECK( pl1.length() == 8 );
3316  CHECK( length(pl1) == 8 );
3317  CHECK( pl1.area() == 4 );
3318  CHECK( area(pl1) == 4 );
3319  CHECK( pl1.centroid() == Point2d(6,7) );
3320  CHECK( centroid(pl1) == Point2d(6,7) );
3321 
3322  auto vpts = pl1.getPts();
3323  CHECK( vpts.size() == 4 );
3324  CHECK( vpts[0] == Point2d(5,6) );
3325 
3326  pl1.translate(1,2);
3327  CHECK( pl1 == CPolyline_<NUMTYPE>( FRect( 6,8, 8,10 ) ) );
3328  }
3329  { // set from Rectangle
3330  FRect r( 5,6, 7,8 );
3331  CPolyline_<NUMTYPE> pl1;
3332  pl1.set(r);
3333 
3334  CHECK( pl1.isSimple() == true );
3335  CHECK( pl1.size() == 4 );
3336  CHECK( pl1.getPoint(0) == Point2d(5,6) );
3337  }
3338  {
3339  OPolyline_<NUMTYPE> po1;
3340  CPolyline_<NUMTYPE> pc1;
3341  std::vector<Point2d> vpt{ {0,0},{2,2}, {2,2}, {4,3} };
3342 
3343  CHECK_THROWS( po1.set( vpt ) ); // cant have two contiguous identical points
3344  CHECK_THROWS( pc1.set( vpt ) ); // cant have two contiguous identical points
3345  }
3346  {
3347  std::vector<Point2d> vpt{ {0,0}, {1,1.5}, {3,5}, {1,4} };
3348 
3349  OPolyline_<NUMTYPE> po1(vpt);
3350  CPolyline_<NUMTYPE> pc1(vpt);
3351 
3352  CHECK( po1.isClosed() == false );
3353  CHECK( pc1.isClosed() == true );
3354 
3355  CHECK( po1.size() == 4 );
3356  CHECK( pc1.size() == 4 );
3357 
3358  CHECK( po1.nbSegs() == 3 );
3359  CHECK( pc1.nbSegs() == 4 );
3360 
3361  CHECK( po1.isSimple() == false );
3362  CHECK( pc1.isSimple() == true );
3363 
3364  CPolyline_<NUMTYPE> pc2(po1);
3365  CHECK( pc2.nbSegs() == 4 );
3366  CHECK( pc2.isSimple() == true );
3367 
3368  FRect bb1( 0,0, 3,5);
3369  CHECK( getBB(po1) == bb1 );
3370  CHECK( getBB(pc1) == bb1 );
3371  CHECK( po1.getBB() == bb1 );
3372  CHECK( pc1.getBB() == bb1 );
3373  }
3374  {
3375  std::vector<Point2d> vpt{ {0,0}, {1,1}, {0,1}, {1,0} };
3376  CPolyline_<NUMTYPE> pc1(vpt);
3377  CHECK( pc1.isClosed() == true );
3378  CHECK( pc1.size() == 4 );
3379  CHECK( pc1.nbSegs() == 4 );
3380  CHECK( pc1.isSimple() == false ); // crossing segments
3381 
3382  pc1.translate(2,1.);
3383  CHECK( pc1.getPoint(0) == Point2d(2,1.) ); // (0,0) translated to (2,1)
3384  }
3385  { // build from std::array
3386  std::array<Point2d,3> pts{{ {0,0}, {1,1}, {0,1} }};
3387  CPolyline_<NUMTYPE> pc(pts);
3388  OPolyline_<NUMTYPE> po(pts);
3389  CHECK( pc.isClosed() == true );
3390  CHECK( po.isClosed() == false );
3391  CHECK( pc.size() == 3 );
3392  CHECK( po.size() == 3 );
3393  CHECK( pc.nbSegs() == 3 );
3394  CHECK( po.nbSegs() == 2 );
3395  }
3396  { // build from std::list
3397  std::list<Point2d> pts{ {0,0}, {1,1}, {0,1} };
3398  CPolyline_<NUMTYPE> pc(pts);
3399  OPolyline_<NUMTYPE> po(pts);
3400  CHECK( pc.isClosed() == true );
3401  CHECK( po.isClosed() == false );
3402  CHECK( pc.size() == 3 );
3403  CHECK( po.size() == 3 );
3404  CHECK( pc.nbSegs() == 3 );
3405  CHECK( po.nbSegs() == 2 );
3406  }
3407  { // build from segment
3409  CPolyline_<NUMTYPE> pc( seg );
3410  OPolyline_<NUMTYPE> po( seg );
3411  CHECK( pc.size() == 2 );
3412  CHECK( po.size() == 2 );
3413  CHECK( pc.getPoint(0) == Point2d(0,0) );
3414  CHECK( po.getPoint(0) == Point2d(0,0) );
3415  CHECK( pc.nbSegs() == 2 );
3416  CHECK( po.nbSegs() == 1 );
3417  }
3418  { // build from segment - 2
3419  Segment_<NUMTYPE> seg; // (0,0) - (1,1)
3420  CPolyline_<NUMTYPE> pc1( seg );
3421  OPolyline_<NUMTYPE> po1( seg );
3422  std::list<Point2d> pts{ {1,1},{0,0} };
3423  CPolyline_<NUMTYPE> pc2(pts);
3424  OPolyline_<NUMTYPE> po2(pts);
3425  CHECK( pc1 == pc2 );
3426  CHECK( po1 == po2 );
3427  }
3428 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6249
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
void polytest_1(const base::PolylineBase< T, U > &pl1)
Definition: homog2d_test.cpp:3264
Segment seg
Definition: homog2d_test.cpp:4051
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
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:10227
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6415
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6465
base::LPBase< typ::IsPoint, FPT > centroid(const base::PolylineBase< PLT, FPT > &pl)
Returns centroid of Polyline (free function)
Definition: homog2d.hpp:10911
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
HOMOG2D_INUMTYPE size(const T &elem)
Returns size of element or variant (free function)
Definition: homog2d.hpp:10257
constexpr bool isClosed() const
Definition: homog2d.hpp:6217
auto getBB() const
Returns Bounding Box of Polyline.
Definition: homog2d.hpp:6230
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:10242
size_t nbSegs(const base::PolylineBase< PLT, FPT > &pl)
Returns the number of segments (free function)
Definition: homog2d.hpp:9931
FRect_< HOMOG2D_INUMTYPE > getBB(const T &t)
Return Bounding Box of primitive or container holding primitives (free function)
Definition: homog2d.hpp:10316
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
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:9911
Here is the call graph for this function:

◆ TEST_CASE() [71/93]

TEST_CASE ( "Polyline setParallelogram"  ,
""  [polyline-setParallelogram] 
)
3451 {
3452  {
3453  Point2d_<NUMTYPE> pt1(0,0);
3454  Point2d_<NUMTYPE> pt2(0,2);
3455  Point2d_<NUMTYPE> pt3(4,5);
3457  pol.setParallelogram( pt1, pt2, pt3 );
3458 
3459  std::vector<Point2d_<NUMTYPE>> vpts{ {0,0}, {0,2}, {4,5}, {4,3} };
3460  CPolyline_<NUMTYPE> pol2(vpts);
3461  CHECK( pol == pol2 );
3462  }
3463 }
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:6769
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] 
)
3466 {
3467  {
3468  CPolyline cp_empty;
3469  CHECK_THROWS( cp_empty.getLmPoint() );
3470  }
3471  {
3472  Point2d_<NUMTYPE> pt( 3, 4 );
3473  std::vector<Point2d_<NUMTYPE>> vpt{ pt };
3474 
3475  CHECK( getLmPoint(vpt).first == pt );
3476  CHECK( getRmPoint(vpt).first == pt );
3477  CHECK( getTmPoint(vpt).first == pt );
3478  CHECK( getBmPoint(vpt).first == pt );
3479  CHECK( getExtremePoint(CardDir::Left,vpt).first == pt );
3480  }
3481  {
3482  std::vector<Point2d_<NUMTYPE>> vpt{ {1,0}, {0,1}, {-1,0}, {0,-1} };
3483  CPolyline cp( vpt );
3484  CHECK( cp.size() == 4 );
3485  CHECK( cp.getLmPoint() == Point2d_<NUMTYPE>(-1,0) );
3486  CHECK( cp.getRmPoint() == Point2d_<NUMTYPE>(1,0) );
3487  CHECK( cp.getTmPoint() == Point2d_<NUMTYPE>(0,1) );
3488  CHECK( cp.getBmPoint() == Point2d_<NUMTYPE>(0,-1) );
3489 
3490  CHECK( getLmPoint(vpt).first == Point2d_<NUMTYPE>(-1,0) );
3491  CHECK( getRmPoint(vpt).first == Point2d_<NUMTYPE>(1,0) );
3492  CHECK( getTmPoint(vpt).first == Point2d_<NUMTYPE>(0,1) );
3493  CHECK( getBmPoint(vpt).first == Point2d_<NUMTYPE>(0,-1) );
3494  }
3495  {
3496  std::vector<Point2d_<NUMTYPE>> vpt{ {0,0}, {1,0}, {2,0}, {2,1}, {2,2}, {1,2}, {0,2}, {0,1} };
3497  CPolyline cp( vpt );
3498  CHECK( cp.size() == 8 );
3499  CHECK( cp.getLmPoint() == Point2d_<NUMTYPE>(0,0) );
3500  CHECK( cp.getRmPoint() == Point2d_<NUMTYPE>(2,0) );
3501  CHECK( cp.getTmPoint() == Point2d_<NUMTYPE>(0,2) );
3502  CHECK( cp.getBmPoint() == Point2d_<NUMTYPE>(0,0) );
3503 
3504  CHECK( getLmPoint(vpt).first == Point2d_<NUMTYPE>(0,0) );
3505  CHECK( getRmPoint(vpt).first == Point2d_<NUMTYPE>(2,0) );
3506  CHECK( getTmPoint(vpt).first == Point2d_<NUMTYPE>(0,2) );
3507  CHECK( getBmPoint(vpt).first == Point2d_<NUMTYPE>(0,0) );
3508  }
3509 }
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:7099
auto getBmPoint(const T &t)
Return Bottom-most point of container holding points.
Definition: homog2d.hpp:6919
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
auto getTmPoint(const T &t)
Return Top-most point of container.
Definition: homog2d.hpp:6944
CHECK_THROWS(CPolyline(-5, 5u))
auto getLmPoint(const T &t)
Return Left-most point of container as a pair holding:
Definition: homog2d.hpp:6991
auto getRmPoint(const T &t)
Return Right-most point of container holding points.
Definition: homog2d.hpp:7032
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:7141
Point2d pt
Definition: homog2d_test.cpp:4052
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] 
)
3512 {
3513  std::vector<Point2d> vpts1{ {0,0}, {1,1.5}, {3,5}, {1,4} };
3514  FRect bb1( 0,0, 3,5 );
3515  {
3516  CHECK( getBB(vpts1) == bb1 );
3517 
3518  CPolyline cpol( vpts1 );
3519  OPolyline opol( vpts1 );
3520  std::vector<CPolyline> vec_c{ cpol };
3521  std::vector<OPolyline> vec_o{ opol };
3522  CHECK( getBB(vec_c) == bb1 );
3523  CHECK( getBB(vec_o) == bb1 );
3524  }
3525  {
3526  std::vector<Segment> vseg;
3527  CHECK_THROWS( getBB(vseg) );
3528  vseg.emplace_back( Segment(0,0,0,1) );
3529  CHECK_THROWS( getBB(vseg) ); // no area !
3530 
3531  vseg.emplace_back( Segment(4,5,6,7) );
3532  FRect bb2( 0,0, 6,7 );
3533  CHECK( getBB(vseg) == bb2 );
3534  }
3535  {
3536  std::list<Circle> vcir;
3537  CHECK_THROWS( getBB(vcir) ); // empty !
3538  vcir.emplace_back( Circle(1,1,1) );
3539  FRect bb3( 0,0, 2,2 );
3540  CHECK( getBB(vcir) == bb3 );
3541  }
3542  {
3543  std::vector<Point2d> vpt{ {0,11} };
3544  CHECK_THROWS( getBB(vpt) ); // need at least 2 points !
3545 
3546  std::list<Point2d> lpt{ {2,11} };
3547  CHECK_THROWS( getBB(lpt) ); // need at least 2 points !
3548 
3549  std::array<Point2d,1> apt;
3550  apt[0] = Point2d{2,11};
3551  CHECK_THROWS( getBB(apt) ); // need at least 2 points !
3552  }
3553 }
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12396
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CHECK_THROWS(CPolyline(-5, 5u))
CPolyline cpol
Definition: homog2d_test.cpp:4048
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:10316
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] 
)
3556 {
3557  {
3558  std::vector<Segment> vec;
3559  auto out1 = getCenters( vec );
3560  CHECK( out1.empty() );
3561 
3562  vec.emplace_back( Segment( 0,0,2,0) );
3563  vec.emplace_back( Segment( 0,1,2,1) );
3564  auto out2 = getCenters( vec );
3565  CHECK( out2.size() == 2 );
3566  CHECK( out2[0] == Point2d(1,0) );
3567  CHECK( out2[1] == Point2d(1,1) );
3568 
3569  auto out3 = getLines( vec );
3570  CHECK( out3.size() == 2 );
3571  CHECK( out3[0] == Line2d( Point2d(0,0), Point2d(5,0) ) );
3572  CHECK( out3[1] == Line2d( Point2d(0,1), Point2d(5,1) ) );
3573  }
3574  {
3575  std::list<Circle> vec;
3576  auto out1 = getCenters( vec );
3577  CHECK( out1.empty() );
3578 
3579  vec.emplace_back( Circle( 0,0, 2) );
3580  vec.emplace_back( Circle( 1,1, 3) );
3581  auto out2 = getCenters( vec );
3582  CHECK( out2.size() == 2 );
3583  CHECK( out2[0] == Point2d(0,0) );
3584  CHECK( out2[1] == Point2d(1,1) );
3585  }
3586  {
3587  std::array<Ellipse,2> vec;
3588  auto out1 = getCenters( vec );
3589  CHECK( out1.size() == 2 ); // because input array has size=2
3590 
3591  vec[0] = Ellipse( 0,0, 2, 3 );
3592  vec[1] = Ellipse( 1,1, 3, 8 );
3593  auto out2 = getCenters( vec );
3594  CHECK( out2.size() == 2 );
3595  CHECK( out2[0] == Point2d(0,0) );
3596  CHECK( out2[1] == Point2d(1,1) );
3597  }
3598 }
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12396
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12380
auto getCenters(const T &vsegs)
Free function, returns middle points of set of segments/circles.
Definition: homog2d.hpp:10747
Ellipse_< HOMOG2D_INUMTYPE > Ellipse
Default ellipse type.
Definition: homog2d.hpp:12406
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:10769
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
Here is the call graph for this function:

◆ TEST_CASE() [75/93]

TEST_CASE ( "Polygon convexity"  ,
""  [polyline-convex] 
)
3601 {
3602  OPolyline_<NUMTYPE> plo;
3603  CPolyline_<NUMTYPE> plc;
3604  CHECK( !plo.isConvex() ); // empty !!
3605  CHECK( !plc.isConvex() );
3606 
3607  CHECK( !isConvex(plc) ); // free function call
3608  CHECK( !isConvex(plo) );
3609 
3610  plo.set( std::vector<Point2d>{ {0,0}, {2,0} } );
3611  plc.set( std::vector<Point2d>{ {0,0}, {2,0} } );
3612  CHECK( !plo.isConvex() ); // 2 pts are fine, but not convex
3613  CHECK( !plc.isConvex() );
3614 
3615  plo.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1} } );
3616  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1} } );
3617  CHECK( !plo.isConvex() ); // 3 pts ok, but open Polyline never convex
3618  CHECK( plc.isConvex() );
3619 
3620  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,2}, {0,2} } );
3621  CHECK( plc.isConvex() );
3622  plc.set( std::vector<Point2d>{ {0,0}, {2,0}, {1,1}, {2,2}, {0,2} } );
3623  CHECK( !plc.isConvex() );
3624 
3625  plc.set( std::vector<Point2d>{ {2,2}, {2,-2}, {-2,-2}, {-2,2} } );
3626  CHECK( plc.isConvex() );
3627  plc.set( std::vector<Point2d>{ {2,2}, {2,-2}, {1,1}, {-2,2} } );
3628  CHECK( !plc.isConvex() );
3629 }
bool isConvex() const
Returns true if polygon is convex.
Definition: homog2d.hpp:7434
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:9921
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6465
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] 
)
3632 {
3633  {
3634  CPolyline_<NUMTYPE> pl1;
3635  CPolyline_<NUMTYPE> pl2; // +-----+
3636  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } ); // | |
3637  pl2.set( std::vector<Point2d>{ {0,0}, {0,1}, {2,1}, {2,0} } ); // +-----+
3638  CHECK( pl1 == pl2 ); // is closed, so the points describe the same thing
3639  }
3640  {
3641  OPolyline_<NUMTYPE> pl1;
3642  OPolyline_<NUMTYPE> pl2; // +-----+ +-----+
3643  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } ); // | and | |
3644  pl2.set( std::vector<Point2d>{ {0,0}, {0,1}, {2,1}, {2,0} } ); // +-----+ + +
3645  CHECK( pl1 != pl2 ); // is open, so they are different
3646 
3647  CPolyline_<NUMTYPE> plc1(pl1);
3648  CPolyline_<NUMTYPE> plc2(pl2);
3649  CHECK( plc1 == plc2 );
3650  }
3651  {
3652  std::vector<Point2d> v1{ {0,0}, {1,0}, {1,1} };
3653  std::vector<Point2d> v2{ {1,1}, {1,0}, {0,0} };
3654 
3655  CPolyline_<NUMTYPE> pl1(v1);
3656  CPolyline_<NUMTYPE> pl2(v2);
3657  CHECK( pl1 == pl2 );
3658  OPolyline_<NUMTYPE> po1(v1);
3659  OPolyline_<NUMTYPE> po2(v2);
3660  CHECK( po1 == po2 );
3661  }
3662 }
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:6465
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] 
)
3666 {
3667  std::vector<Point2d_<NUMTYPE>> vpts{ {0,0}, {1,0}, {1,1} };
3668 
3669  std::vector<Segment_<NUMTYPE>> vseg_o;
3670  std::vector<Segment_<NUMTYPE>> vseg_c;
3671  vseg_o.emplace_back( Segment_<NUMTYPE>( 0,0, 1,0 ) );
3672  vseg_o.emplace_back( Segment_<NUMTYPE>( 1,0, 1,1 ) );
3673  vseg_c = vseg_o;
3674  vseg_c.emplace_back( Segment_<NUMTYPE>( 1,1, 0,0 ) );
3675 
3676  CPolyline_<NUMTYPE> cpol(vpts);
3677  OPolyline_<NUMTYPE> opol(vpts);
3678  CHECK( cpol.isClosed() );
3679  CHECK( !opol.isClosed() );
3680 
3681  CHECK( cpol.size() == 3 );
3682  CHECK( opol.size() == 3 );
3683 
3684  CHECK( cpol.getPts() == vpts );
3685  CHECK( opol.getPts() == vpts );
3686 
3687  CHECK( cpol.getSegs() == vseg_c );
3688  CHECK( opol.getSegs() == vseg_o );
3689 
3690  std::vector<OSegment_<NUMTYPE>> voseg_o; // oriented segments
3691  std::vector<OSegment_<NUMTYPE>> voseg_c;
3692 
3693  auto os0 = OSegment_<NUMTYPE>( 0,0, 1,0 );
3694  auto os1 = OSegment_<NUMTYPE>( 1,0, 1,1 );
3695  auto os2 = OSegment_<NUMTYPE>( 1,1, 0,0 );
3696  voseg_o.emplace_back( os0 );
3697  voseg_o.emplace_back( os1 );
3698  voseg_c = voseg_o;
3699  voseg_c.emplace_back( os2 );
3700 
3701  CHECK( cpol.getOSegs() == voseg_c );
3702  CHECK( opol.getOSegs() == voseg_o );
3703 
3704  CHECK( cpol.getOSegment(0) == os0 );
3705  CHECK( opol.getOSegment(0) == os0 );
3706 
3707  CHECK( cpol.getOSegment(1) == os1 );
3708  CHECK( opol.getOSegment(1) == os1 );
3709 
3710  CHECK( cpol.getOSegment(2) == os2 );
3711  CHECK_THROWS( opol.getOSegment(2) );
3713 }
std::vector< Segment_< FPT > > getSegs() const
Returns (as a copy) the segments of the polyline.
Definition: homog2d.hpp:6318
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:6312
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
constexpr bool isClosed() const
Definition: homog2d.hpp:6217
CPolyline cpol
Definition: homog2d_test.cpp:4048
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:6215
OSegment_< FPT > getOSegment(size_t idx) const
Returns one oriented segment of the polyline.
Definition: homog2d.hpp:6357
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] 
)
3717 {
3718  OPolyline_<NUMTYPE> plo;
3719  CPolyline_<NUMTYPE> plc;
3720  OPolyline_<NUMTYPE> plo_ff;
3721  CPolyline_<NUMTYPE> plc_ff;
3722  std::vector<Point2d> vpts{ {0,0}, {2,0}, {1,1} };
3723  {
3724  plo.set( vpts );
3725  plc.set( vpts );
3726  plo.rotate( Rotate::CCW );
3727  plc.rotate( Rotate::CCW );
3728  std::vector<Point2d> vpts2{ {0,0},{0,2},{-1,1} };
3729  OPolyline_<NUMTYPE> plo2( vpts2 );
3730  CPolyline_<NUMTYPE> plc2( vpts2 );
3731  CHECK( plo == plo2 );
3732  CHECK( plc == plc2 );
3733 
3734  plo_ff.set( vpts );
3735  plc_ff.set( vpts );
3736  rotate( plo_ff, Rotate::CCW );
3737  rotate( plc_ff, Rotate::CCW );
3738  CHECK( plo == plo_ff );
3739  CHECK( plc == plc_ff );
3740  }
3741  {
3742  plo.set( vpts );
3743  plc.set( vpts );
3744  plo.rotate( Rotate::VMirror );
3745  plc.rotate( Rotate::VMirror );
3746  std::vector<Point2d> vpts2{ {0,0},{-2,0},{-1,1} };
3747  OPolyline_<NUMTYPE> plo2( vpts2 );
3748  CPolyline_<NUMTYPE> plc2( vpts2 );
3749  CHECK( plo == plo2 );
3750  CHECK( plc == plc2 );
3751  }
3752  {
3753  plo.set( vpts );
3754  plc.set( vpts );
3755  plo.rotate( Rotate::HMirror );
3756  plc.rotate( Rotate::HMirror );
3757  std::vector<Point2d> vpts2{ {0,0},{2,0},{1,-1} };
3758  OPolyline_<NUMTYPE> plo2( vpts2 );
3759  CPolyline_<NUMTYPE> plc2( vpts2 );
3760  CHECK( plo == plo2 );
3761  CHECK( plc == plc2 );
3762  }
3763 }
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:7269
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6465
void rotate(T &prim, Rotate rot)
Rotates the primitive (only available for Polyline and FRect) around (0,0)
Definition: homog2d.hpp:9950
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] 
)
3766 {
3767  CPolyline_<NUMTYPE> pl1;
3768  {
3769  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } );
3770  CHECK( pl1.size() == 4 );
3771  CHECK( pl1.nbSegs() == 4 );
3772  CHECK( pl1.isSimple() == true );
3773  CHECK( pl1.area() == 2. );
3774  }
3775  {
3776  pl1.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,2}, {1,2}, {1,1}, {0,1} } );
3777  CHECK( pl1.size() == 6 );
3778  CHECK( pl1.nbSegs() == 6 );
3779  CHECK( pl1.isSimple() == true );
3780  CHECK( pl1.area() == 3. );
3781  }
3782  OPolyline_<NUMTYPE> plo;
3783  plo.set( std::vector<Point2d>{ {0,0}, {2,0}, {2,1}, {0,1} } );
3784  CHECK( plo.isSimple() == false );
3785  CHECK( plo.area() == 0. );
3786 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6249
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
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:6465
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
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:7485
Here is the call graph for this function:

◆ TEST_CASE() [80/93]

TEST_CASE ( "Polyline comparison 2"  ,
""  [polyline-comp-2] 
)
3789 {
3790  {
3791  OPolyline_<NUMTYPE> pa,pb;
3792  CHECK( pa == pb );
3793  }
3794  {
3795  CPolyline_<NUMTYPE> pa,pb;
3796  CHECK( pa == pb );
3797  }
3798 
3799  OPolyline_<NUMTYPE> pl2( std::vector<Point2d>{ {7,8},{3,4},{5,6} } );
3800  OPolyline_<NUMTYPE> pl1( std::vector<Point2d>{ {3,4},{5,6},{7,8} } );
3801 
3802  {
3803  OPolyline_<NUMTYPE> p1 = pl1;
3804  OPolyline_<NUMTYPE> p2 = pl2;
3805 
3806  CHECK( p1.isClosed() == false );
3807  CHECK( p1.isNormalized() == false );
3808  CHECK( p2.isNormalized() == false );
3809  CHECK( p1!=p2 );
3810  }
3811  {
3812  CPolyline_<NUMTYPE> p1 = pl1; // build a closed one from an open one
3813  CPolyline_<NUMTYPE> p2 = pl2;
3814 
3815  CHECK( p1.isClosed() == true );
3816  CHECK( p1.isNormalized() == false );
3817  CHECK( p2.isNormalized() == false );
3818  CHECK( (p1==p2) == true );
3819  CHECK( p1.isNormalized() == true );
3820  CHECK( p2.isNormalized() == true );
3821  }
3822  {
3823  CPolyline_<NUMTYPE> p2( std::vector<Point2d>{ {1,2},{1,1},{2,1} } );
3824  CPolyline_<NUMTYPE> p1( std::vector<Point2d>{ {1,1},{2,1},{1,2} } );
3825 
3826  CHECK( p1.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3827  CHECK( p2.getPoint(0) == Point2d_<NUMTYPE>(1,2) );
3828  CHECK( p1 == p2 ); // normalizing
3829  CHECK( p1.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3830  CHECK( p2.getPoint(0) == Point2d_<NUMTYPE>(1,1) );
3831  }
3832  {
3833  CPolyline pa, pb;
3834  {
3835 #include "figures_test/polyline_comp_1a.code"
3836  pa = pl;
3837  }
3838  {
3839 #include "figures_test/polyline_comp_1b.code"
3840  pb = pl;
3841  }
3842  CHECK( pa.size() == pb.size() );
3843  CHECK( pa != pb );
3844  }
3845 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
constexpr bool isClosed() const
Definition: homog2d.hpp:6217
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
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] 
)
3933 {
3934  {
3936 
3937  pl.set( FRect_<NUMTYPE>(1,1,3,3) );
3938  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3939 
3940  std::vector<Point2d> v1{ {0,0}, {2,0}, {2,2}, {1,2}, {1,1}, {0,1} };
3941  pl.set( v1 );
3942  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3943 
3944  std::rotate( v1.begin(), v1.begin()+1, v1.end() );
3945  pl.set( v1 );
3946  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 5 );
3947 
3948  std::rotate( v1.begin(), v1.begin()+1, v1.end() );
3949  pl.set( v1 );
3950  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 4 );
3951  }
3952  {
3953 #include "figures_test/polyline_chull_1.code"
3954  auto vp = pl.getPts();
3955  CHECK( priv::chull::getPivotPoint(pl.getPts() ) == 0 );
3956  auto vout = priv::chull::sortPoints( vp, 0 );
3957  CHECK( vout == std::vector<size_t>{ 0,1,2,3 } );
3958  auto ch = convexHull( pl );
3959  CHECK( ch == CPolyline(
3960  std::vector<Point2d>{
3961  {0,0},{3,0},{0,3}
3962  }
3963  )
3964  );
3965  }
3966  {
3967  CPolyline pl1;
3968  auto ch1 = convexHull( pl1 );
3969  CHECK( ch1.size() == 0 );
3970  auto ch2 = pl1.convexHull();
3971  CHECK( ch2.size() == 0 );
3972  }
3973  {
3974  CPolyline pl1( std::vector<Point2d>{ {1,1}, {2,2} });
3975  auto ch1 = convexHull( pl1 );
3976  CHECK( ch1.size() == 2 );
3977  auto ch2 = pl1.convexHull();
3978  CHECK( ch2.size() == 2 );
3979  }
3980 }
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:11462
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
CPolyline_< FPT > convexHull() const
Return convex hull (member function implementation)
Definition: homog2d.hpp:11627
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12402
void set(const CONT &vec)
Set from vector/array/list of points (discards previous points)
Definition: homog2d.hpp:6465
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
void rotate(T &prim, Rotate rot)
Rotates the primitive (only available for Polyline and FRect) around (0,0)
Definition: homog2d.hpp:9950
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:11452
CPolyline_< FPT > convexHull(const base::PolylineBase< CT, FPT > &input)
Compute Convex Hull of a Polyline (free function)
Definition: homog2d.hpp:11540
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] 
)
3992 {
3993 // 1 - make sure calling with empty container throws
3994  std::vector<Point2d_<NUMTYPE>> vec;
3995  std::vector<Point2d_<NUMTYPE>> lst;
3996  std::array<Point2d_<NUMTYPE>,0> arr0; // very unlikely, but... who knows?
3997  checkSizeNF( Point2d_<NUMTYPE>(), vec );
3998  checkSizeNF( Point2d_<NUMTYPE>(), lst );
3999  checkSizeNF( Point2d_<NUMTYPE>(), arr0 );
4000 
4001 // 2 - make sure calling with container holding only 1 point also throws
4002  vec.emplace_back( Point2d_<NUMTYPE>() ); // add point (0,0)
4003  lst.emplace_back( Point2d_<NUMTYPE>() );
4004  std::array<Point2d_<NUMTYPE>,1> arr;
4005 
4006  checkSizeNF( Point2d_<NUMTYPE>(), vec );
4007  checkSizeNF( Point2d_<NUMTYPE>(), lst );
4008  checkSizeNF( Point2d_<NUMTYPE>(), arr );
4009 
4010 // 3 - check behavior if query point is in the container (only for vector)
4011  {
4012  Point2d_<NUMTYPE> pt1(1,1);
4013  Point2d_<NUMTYPE> pt0;
4014  vec.emplace_back( pt1 );
4015  auto resN = findNearestPoint( pt0, vec ); // check for (0,0)
4016  auto resF = findFarthestPoint( pt0, vec );
4017  CHECK( resN == 1 ); // both will return
4018  CHECK( resF == 1 ); // second point
4019 
4020  resN = findNearestPoint( pt1, vec ); // check for (1,1)
4021  resF = findFarthestPoint( pt1, vec );
4022  CHECK( resN == 0 ); // both will return
4023  CHECK( resF == 0 ); // first point
4024 
4025  auto pres = findNearestFarthestPoint( pt0, vec );
4026  CHECK( pres.first == 1 );
4027  CHECK( pres.second == 1 );
4028  auto pres2 = findNearestFarthestPoint( pt1, vec );
4029  CHECK( pres2.first == 0 );
4030  CHECK( pres2.second == 0 );
4031  }
4032 
4033 // 4 - check general behavior
4034  { // 0 1 2 3 4
4035  std::vector<Point2d_<NUMTYPE>> vec2{ {0,0}, {3,0}, {4,0}, {5,6}, {7,8} };
4036  Point2d_<NUMTYPE> qpt(4,5);
4037  auto pres = findNearestFarthestPoint( qpt, vec2 );
4038  auto resN = findNearestPoint( qpt, vec2 );
4039  auto resF = findFarthestPoint( qpt, vec2 );
4040  CHECK( pres.first == resN );
4041  CHECK( pres.second == resF );
4042  CHECK( 3 == resN );
4043  CHECK( 0 == resF );
4044  }
4045 }
auto findNearestFarthestPoint(const Point2d_< FPT > &pt, const T &cont)
Returns indexes of points in container cont that are nearest/farthest.
Definition: homog2d.hpp:11171
void checkSizeNF(const PT &pt, const CONT &cont)
Definition: homog2d_test.cpp:3984
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:11160
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:11152
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
4079 {
4080  OPolyline opol;
4081 
4082 }
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] 
)
4091 {
4093  var = Circle_<NUMTYPE>{};
4095  // TODO
4096 }
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] 
)
4099 {
4100  std::vector<CommonType_<NUMTYPE>> vvar;
4101  vvar.push_back( Circle_<NUMTYPE>{} );
4102  vvar.push_back( Segment_<NUMTYPE>{} );
4103  vvar.push_back( Line2d_<NUMTYPE>{} );
4104 
4105  {
4106  auto var0 = vvar[0];
4108  CHECK( std::visit( fct::TypeFunct{}, var0 ) == Type::Circle );
4109  CHECK( c == Circle() );
4110 
4111  auto var1 = vvar[1];
4113  CHECK( type( var1 ) == Type::Segment );
4114  CHECK( s == Segment() );
4115 
4116  auto var2 = vvar[2];
4118  CHECK( type( var2 ) == Type::Line2d );
4119  }
4120 }
A circle.
Definition: homog2d.hpp:378
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12396
Line2d_< HOMOG2D_INUMTYPE > Line2d
Default line type, uses double as numerical type.
Definition: homog2d.hpp:12380
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:10194
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
4130 {
4132  {
4133  Circle c( 50,50,20);
4134  img::Image<img::SvgImage> im(200,200);
4135  c.draw( im );
4136  im.write( "BUILD/test_svg_11.svg" );
4137 
4138  tinyxml2::XMLDocument doc; // load the file that we just created
4139  doc.LoadFile( "BUILD/test_svg_11.svg" );
4140 
4141  h2d::svg::Visitor visitor;
4142  doc.Accept( &visitor );
4143  const auto& data = visitor.get();
4144  CHECK( data.size() == 1 );
4145  auto elem = data.at(0);
4146  CHECK( type( elem ) == Type::Circle );
4148  CHECK( cir.radius() == 20 );
4149  }
4150  { // this test makes sure the <g> element is ignored
4151  tinyxml2::XMLDocument doc;
4152  doc.LoadFile( "misc/other/test_svg_import_1.svg" );
4153  h2d::svg::Visitor visitor;
4154  doc.Accept( &visitor );
4155  const auto& data = visitor.get();
4156  CHECK( data.size() == 3 );
4157  for( const auto& elem: data )
4158  CHECK( type( elem ) == Type::Circle );
4159  }
4160  { // read a file with 3 circles, one rect, one segment and a polygon
4161  tinyxml2::XMLDocument doc;
4162  doc.LoadFile( "misc/other/test_svg_import_2.svg" );
4163  h2d::svg::Visitor visitor;
4164  doc.Accept( &visitor );
4165  const auto& data = visitor.get();
4166  CHECK( data.size() == 6 );
4167 
4168  CHECK( type( data.at(3) ) == Type::Segment );
4169  CHECK( type( data.at(4) ) == Type::FRect );
4170  CHECK( type( data.at(5) ) == Type::CPolyline );
4171  }
4172 }
A circle.
Definition: homog2d.hpp:378
FRect_< HOMOG2D_INUMTYPE > FRect
Default rectangle type.
Definition: homog2d.hpp:12399
Segment_< HOMOG2D_INUMTYPE > Segment
Default segment type.
Definition: homog2d.hpp:12392
Circle_< HOMOG2D_INUMTYPE > Circle
Default circle type.
Definition: homog2d.hpp:12396
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:10194
Convert std::variant object into the underlying type.
Definition: homog2d.hpp:1093
CPolyline_< HOMOG2D_INUMTYPE > CPolyline
Default polyline type.
Definition: homog2d.hpp:12402
Visitor class, derived from the tinyxml2 visitor class. Used to import SVG data.
Definition: homog2d.hpp:12868
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:12908
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:3294
Circle cir
Definition: homog2d_test.cpp:4054
Here is the call graph for this function:

◆ TEST_CASE() [87/93]

TEST_CASE ( "SVG Import Ellipse ,
""  [svg_import_ell] 
)
4175 {
4176  tinyxml2::XMLDocument doc;
4177  doc.LoadFile( "misc/other/test_svg_import_3.svg" );
4178  h2d::svg::Visitor visitor;
4179  doc.Accept( &visitor );
4180  const auto& data = visitor.get();
4181  CHECK( data.size() == 3 );
4182  for( const auto& p: data )
4183  {
4184  if( type( p ) == Type::Ellipse )
4185  {
4186  Ellipse ell( 150, 100, 60, 15, 20*M_PI/180. );
4187  const EllipseD ell2 = fct::VariantUnwrapper{ p };
4188  CHECK( ell == ell2 );
4189  }
4190  }
4191 }
Ellipse_< HOMOG2D_INUMTYPE > Ellipse
Default ellipse type.
Definition: homog2d.hpp:12406
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:10194
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:12868
Ellipse ell
Definition: homog2d_test.cpp:4055
const std::vector< CommonType_< double > > & get() const
Used to access the data once the file has been read.
Definition: homog2d.hpp:12908
Here is the call graph for this function:

◆ TEST_CASE() [88/93]

TEST_CASE ( "SVG Import path 1"  ,
""  [svg_import_path_1] 
)
4194 {
4195  { // empty string
4196  const char* s1 = "";
4198  }
4199  {
4200  const char* s1 ="10 20 30 40";
4201  const auto& res = svg::svgp::parsePath( s1 );
4202  CHECK( res.first.size() == 1 ); // one vector
4203  CHECK( res.first[0].size() == 2 ); // holding two points
4204  CHECK( res.first[0][0] == Point2d(10,20) );
4205  CHECK( res.first[0][1] == Point2d(30,40) );
4206  CHECK( res.second == false );
4207  }
4208 
4209  {
4210  const char* s1 ="10 20 30 40z";
4211  auto res = svg::svgp::parsePath( s1 );
4212  CHECK( res.first.size() == 1 );
4213  CHECK( res.first[0].size() == 2 );
4214  CHECK( res.second == true );
4215  }
4216  {
4217  const char* s1 ="10 20 m 1 2 3 4z"; //relative and "Move To" (=>so two vectors in output)
4218  auto res = svg::svgp::parsePath( s1 );
4219  CHECK( res.first.size() == 2 );
4220  CHECK( res.first[0].size() == 1 );
4221  CHECK( res.first[1].size() == 2 );
4222  CHECK( res.first[0][0] == Point2d(10,20) );
4223  CHECK( res.first[1][0] == Point2d(11,22) );
4224  CHECK( res.first[1][1] == Point2d(14,26) );
4225  CHECK( res.second == true );
4226  }
4227  {
4228  const char* s1 ="10 20 H 30 40"; //horizontal line
4229  auto res = svg::svgp::parsePath( s1 );
4230  CHECK( res.first.size() == 1 );
4231  CHECK( res.first[0].size() == 3 );
4232  CHECK( res.first[0][0] == Point2d(10,20) );
4233  CHECK( res.first[0][1] == Point2d(30,20) );
4234  CHECK( res.first[0][2] == Point2d(40,20) );
4235  CHECK( res.second == false);
4236  }
4237  {
4238  const char* s1 ="10"; // missing second value
4240  }
4241  {
4242  const char* s1 ="10 20 30"; // missing second value
4244  }
4245  {
4246  const char* s1 ="M10 20 C 30"; // C command not handled
4248  }
4249 }
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:12800
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] 
)
4259 {
4260  namespace bg = boost::geometry;
4261  bg::model::point<double, 2, boost::geometry::cs::cartesian> ptb1(3,4);
4262  bg::model::d2::point_xy<double> ptb2(5,6);
4263  Point2d_<NUMTYPE> pt1(ptb1);
4264  Point2d_<NUMTYPE> pt2(ptb2);
4265  CHECK( pt1 == Point2d_<NUMTYPE>(3,4) );
4266  CHECK( pt2 == Point2d_<NUMTYPE>(5,6) );
4267 
4268  pt1 = ptb1; // using assignment operator
4269  pt2 = ptb2;
4270  CHECK( pt1 == Point2d_<NUMTYPE>(3,4) );
4271  CHECK( pt2 == Point2d_<NUMTYPE>(5,6) );
4272 }
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] 
)
4275 {
4276  Point2d_<NUMTYPE> ref1(3,4);
4277  Point2d_<NUMTYPE> ref2(5,6);
4278  namespace bg = boost::geometry;
4279  using point_t1 = bg::model::point<double, 2, bg::cs::cartesian>;
4280  using point_t2 = bg::model::d2::point_xy<double>;
4281 
4282  auto pt1 = getPt<point_t1>( ref1 );
4283  auto pt2 = getPt<point_t2>( ref2 );
4284  CHECK( bg::get<0>(pt1) == ref1.getX() );
4285  CHECK( bg::get<0>(pt2) == ref2.getX() );
4286 }
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] 
)
4289 {
4290  namespace bg = boost::geometry;
4291  std::vector<Point2d> vin;
4292  vin.push_back( Point2d(0.0, 0.0) );
4293  vin.push_back( Point2d(0.0, 5.0));
4294  vin.push_back( Point2d(5.0, 5.0));
4295  auto vout = getPts<bg::model::d2::point_xy<float>>(vin); // convert to a vector of boost geometry points
4296  CHECK( vout.size() == 3 );
4297 }
CHECK(s1.getPointAt(0)==Point2d_< NUMTYPE >(0, 0))
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
Here is the call graph for this function:

◆ TEST_CASE() [92/93]

TEST_CASE ( "Opencv build H"  ,
""  [test_opencv2] 
)
4308 {
4309  std::vector<Point2d_<NUMTYPE>> v1(4);
4310  std::vector<Point2d_<NUMTYPE>> v2(4);
4312  H.buildFrom4Points( v1, v2 );
4313  buildFrom4Points( v1, v2 );
4314 }
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:4772
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:4797
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] 
)
4317 {
4318  cv::Mat mat_64 = cv::Mat::eye(3, 3, CV_64F);
4319  cv::Mat mat_32 = cv::Mat::eye(3, 3, CV_32F);
4320  INFO( "assignment operator()" )
4321  {
4322  cv::Mat cvmat = cv::Mat::ones(3,3, CV_32F );
4323  Homogr H;
4324  H = cvmat;
4325  CHECK( H.value(0,0) == 1.);
4326  CHECK( H.value(1,1) == 1.);
4327  CHECK( H.value(1,0) == 1.);
4328  CHECK( H.value(0,1) == 1.);
4329 
4330  cv::Mat cvmat2 = cv::Mat::ones(3,3, CV_32F );
4331  Homogr H2 = cvmat;
4332  CHECK( H2.value(0,0) == 1.);
4333  CHECK( H2.value(1,1) == 1.);
4334  CHECK( H2.value(1,0) == 1.);
4335  CHECK( H2.value(0,1) == 1.);
4336 
4337  H = mat_64;
4338  CHECK( H.value(0,0) == 1.);
4339  CHECK( H.value(1,1) == 1.);
4340  CHECK( H.value(1,0) == 0.);
4341  CHECK( H.value(0,1) == 0.);
4342 
4343  H = mat_32;
4344  CHECK( H.value(0,0) == 1.);
4345  CHECK( H.value(1,1) == 1.);
4346  CHECK( H.value(1,0) == 0.);
4347  CHECK( H.value(0,1) == 0.);
4348  }
4349  INFO( "default copyTo()" )
4350  {
4351  Homogr H;
4352  cv::Mat mat;
4353  CHECK_THROWS( H.copyTo( mat, 111 ) );
4354  CHECK_NOTHROW( H.copyTo( mat ) );
4355  CHECK( (
4356  (mat.at<double>(0,0) == 1.0)
4357  && (mat.at<double>(0,1) == 0.0)
4358  && (mat.at<double>(0,2) == 0.0)
4359  ) );
4360  CHECK( mat.channels() == 1 );
4361  CHECK( mat.type() == CV_64F );
4362  }
4363  INFO( "copyTo() with CV_64F" )
4364  {
4365  Homogr H;
4366  cv::Mat mat;
4367  H.copyTo( mat, CV_64F );
4368  CHECK( (
4369  (mat.at<double>(0,0) == 1.0)
4370  && (mat.at<double>(0,1) == 0.0)
4371  && (mat.at<double>(0,2) == 0.0)
4372  ) );
4373  CHECK( mat.channels() == 1 );
4374  CHECK( mat.type() == CV_64F );
4375  }
4376  INFO( "copyTo() with CV_32F" )
4377  {
4378  Homogr H;
4379  cv::Mat mat;
4380  H.copyTo( mat, CV_32F );
4381  CHECK( (
4382  (mat.at<float>(0,0) == 1.0)
4383  && (mat.at<float>(0,1) == 0.0)
4384  && (mat.at<float>(0,2) == 0.0)
4385  ) );
4386  CHECK( mat.channels() == 1 );
4387  CHECK( mat.type() == CV_32F );
4388  }
4389  INFO( "Copy to OpenCv points" )
4390  {
4391  Point2d_<NUMTYPE> pt(1.,2.);
4392  { // free function
4393  cv::Point2d cvpt1 = getCvPtd( pt ); // double
4394  CHECK( (cvpt1.x == 1. && cvpt1.y == 2.) );
4395  cv::Point2f cvpt2 = getCvPtf( pt ); // float
4396  CHECK( (cvpt2.x == 1. && cvpt2.y == 2.) );
4397  cv::Point2i cvpt3 = getCvPti( pt ); // integer point
4398  CHECK( (cvpt3.x == 1 && cvpt3.y == 2) );
4399 
4400  auto cvpt_1 = getPt<cv::Point2d>( pt );
4401  auto cvpt_2 = getPt<cv::Point2f>( pt );
4402  auto cvpt_3 = getPt<cv::Point2i>( pt );
4403  }
4404  {
4405  cv::Point2d cvpt1 = pt.getCvPtd() ;
4406  CHECK( (cvpt1.x == 1. && cvpt1.y == 2.) );
4407  cv::Point2f cvpt2 = pt.getCvPtf() ;
4408  CHECK( (cvpt2.x == 1. && cvpt2.y == 2.) );
4409  cv::Point2i cvpt3 = pt.getCvPti() ; // integer point
4410  CHECK( (cvpt3.x == 1 && cvpt3.y == 2 ) );
4411 
4412  auto cvpt_1 = pt.getPt<cv::Point2d>();
4413  auto cvpt_2 = pt.getPt<cv::Point2f>();
4414  auto cvpt_3 = pt.getPt<cv::Point2i>();
4415  }
4416  { // input: vector of "double" points
4417  // converted into "float" Opencv points
4418  std::vector<Point2d> v{ Point2d(1,2), Point2d(5,6), Point2d(3,4) };
4419  auto vcv1 = getPts<cv::Point2d>( v );
4420  CHECK( vcv1.size() == 3 );
4421  auto vcv2 = getPts<cv::Point2f>( v );
4422  CHECK( vcv2.size() == 3 );
4423  auto vcv3 = getPts<cv::Point2i>( v );
4424  CHECK( vcv3.size() == 3 );
4425  }
4426  }
4427  INFO( "Fetch from OpenCv points" )
4428  {
4429  cv::Point2d ptd(1,2);
4430  cv::Point2f ptf(1,2);
4431  cv::Point2f pti(1,2);
4432  { // test of constructor
4433  Point2d p1(ptd);
4434  CHECK(( p1.getX() == 1. && p1.getY() == 2. ));
4435  Point2d_<NUMTYPE> p2(ptf);
4436  CHECK(( p2.getX() == 1. && p2.getY() == 2. ));
4437  Point2d_<NUMTYPE> p3(pti);
4438  CHECK(( p3.getX() == 1. && p3.getY() == 2. ));
4439  }
4440  { // test of assignment operator
4441  Point2d p1 = ptd;
4442  CHECK(( p1.getX() == 1 && p1.getY() == 2. ));
4443  Point2d_<NUMTYPE> p2 = ptf;
4444  CHECK(( p2.getX() == 1 && p2.getY() == 2. ));
4445  Point2d_<NUMTYPE> p3 = pti;
4446  CHECK(( p3.getX() == 1 && p3.getY() == 2. ));
4447  }
4448  }
4449  INFO( "Build line using OpenCv points" )
4450  {
4451  Line2d_<NUMTYPE> lia( cv::Point2d(100,200) );
4452 // Line2d_<NUMTYPE> lib( Point2d(100,200) );
4453 // CHECK( lia == lib );
4454  }
4455 }
cv::Point2d getCvPtd(const Point2d_< FPT > &pt)
Free function to return an OpenCv point (double)
Definition: homog2d.hpp:4596
cv::Point2f getCvPtf(const Point2d_< FPT > &pt)
Free function to return an OpenCv point (float)
Definition: homog2d.hpp:4603
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:4610
ANY getPt() const
Generic transformation into any other point type, as long as it provides a 2-args constructor (is the...
Definition: homog2d.hpp:4202
void copyTo(cv::Mat &, int type=CV_64F) const
Copy matrix to Opencv cv::Mat.
Definition: homog2d.hpp:11647
Point2d_< HOMOG2D_INUMTYPE > Point2d
Default point type, uses double as numerical type.
Definition: homog2d.hpp:12383
CHECK_THROWS(CPolyline(-5, 5u))
const FPT & value(size_t r, size_t c) const
Definition: homog2d.hpp:1507
cv::Point2i getCvPtf() const
Definition: homog2d.hpp:4440
cv::Point2i getCvPti() const
Definition: homog2d.hpp:4438
cv::Point2i getCvPtd() const
Definition: homog2d.hpp:4439
HOMOG2D_INUMTYPE getX() const
Definition: homog2d.hpp:4133
Point2d pt
Definition: homog2d_test.cpp:4052
HOMOG2D_INUMTYPE getY() const
Definition: homog2d.hpp:4138
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