homog2d library
Public Types | Public Member Functions | Friends | List of all members
h2d::base::PolylineBase< PLT, FPT > Class Template Reference

Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_. More...

#include <homog2d.hpp>

Inheritance diagram for h2d::base::PolylineBase< PLT, FPT >:
Inheritance graph
[legend]
Collaboration diagram for h2d::base::PolylineBase< PLT, FPT >:
Collaboration graph
[legend]

Public Types

using FType = FPT
 
using SType = std::conditional< std::is_same_v< PLT, typ::IsClosed >, typ::T_CPol, typ::T_OPol >
 

Public Member Functions

void draw (img::Image< img::SvgImage > &, img::DrawParams dp=img::DrawParams()) const
 Draw Polyline (SVG implementation) More...
 
void draw (img::Image< cv::Mat > &, img::DrawParams dp=img::DrawParams()) const
 Draw PolylineBase (Opencv implementation) More...
 
std::vector< Line2d_< HOMOG2D_INUMTYPE > > getBisectorLines () const
 
template<typename T >
PolylineBase< typ::IsClosed, FPT > getOffsetPoly (T value, OffsetPolyParams p=OffsetPolyParams{}) const
 Return an "offsetted" closed polyline, requires simple polygon (CPolyline AND no crossings) as input. More...
 
template<typename T , typename std::enable_if< trait::IsShape< T >::value, T >::type * = nullptr>
detail::IntersectM< FPT > intersects (const T &other) const
 Polyline intersection with Line, Segment, FRect, Circle. More...
 
template<typename T , typename std::enable_if<(trait::HasArea< T >::value &&!trait::PolIsClosed< T >::value), T >::type * = nullptr>
bool isInside (const T &prim) const
 Polyline isInside other primitive. More...
 
template<typename T , typename std::enable_if< trait::PolIsClosed< T >::value, T >::type * = nullptr>
bool isInside (const T &cpol) const
 Polyline isInside other CPolyline. More...
 
Type type () const
 
Constructors
 PolylineBase ()=default
 Default constructor. More...
 
template<typename FPT2 >
 PolylineBase (const FRect_< FPT2 > &rect)
 Constructor from FRect. Enabled for "closed" type, disabled for "open" type. More...
 
template<typename FPT2 >
 PolylineBase (const Segment_< FPT2 > &seg)
 
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * = nullptr>
 PolylineBase (const T &vec)
 Constructor from a vector of points. More...
 
template<typename FPT2 , typename T >
 PolylineBase (FPT2 rad, T n)
 Constructor that builds a regular convex polygon of n points at a distance rad, centered at (0,0). More...
 
template<typename FPT2 >
constexpr PolylineBase (const CPolyline_< FPT2 > &other)
 Copy-Constructor from Closed Polyline. More...
 
template<typename FPT2 >
 PolylineBase (const OPolyline_< FPT2 > &other)
 Copy-Constructor from Open Polyline. More...
 
template<typename BPT , bool CLKW, bool CLOSED>
 PolylineBase (const boost::geometry::model::polygon< BPT, CLKW, CLOSED > &bgpol)
 Constructor from a boost geometry polygon, see misc/test_files/bg_test_1.cpp. More...
 
Attributes access
size_t size () const
 Returns the number of points. More...
 
constexpr bool isClosed () const
 
HOMOG2D_INUMTYPE length () const
 Returns length of Polyline. More...
 
HOMOG2D_INUMTYPE area () const
 Returns area of polygon (computed only if necessary) More...
 
bool isSimple () const
 Returns true if object is a polygon (closed, and no segment crossing) More...
 
auto getBB () const
 Returns Bounding Box of Polyline. More...
 
LPBase< typ::IsPoint, HOMOG2D_INUMTYPEcentroid () const
 Compute centroid of polygon. More...
 
size_t nbSegs () const
 Returns the number of segments. If "closed",. More...
 
Point2d_< FPT > getExtremePoint (CardDir) const
 Get Top-most / Bottom-most / Left-most / Right-most point. More...
 
Point2d_< FPT > getTmPoint () const
 Return Top-most point of Polyline. More...
 
Point2d_< FPT > getBmPoint () const
 Return Bottom-most point of Polyline. More...
 
Point2d_< FPT > getLmPoint () const
 Return Left-most point of Polyline. More...
 
Point2d_< FPT > getRmPoint () const
 Return Right-most point of Polyline. More...
 
bool isConvex () const
 Returns true if polygon is convex. More...
 
Modifiers (non-const member functions)
void clear ()
 Clear all (does not change the "open/close" status). More...
 
template<typename FPT2 >
void rotate (Rotate, const Point2d_< FPT2 > &)
 Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt. More...
 
void rotate (Rotate)
 Rotates the polyline by either 90°, 180°, 270° (-90°) at point (0,0) More...
 
void minimize ()
 Miminize the PolylineBase: remove all points that lie in the middle of two segments with same angle. More...
 
template<typename TX , typename TY >
void translate (TX dx, TY dy)
 Translate Polyline using dx, dy. More...
 
template<typename T1 , typename T2 >
void translate (const std::pair< T1, T2 > &ppt)
 Translate Polyline, using a pair of numerical values. More...
 
template<typename TX , typename TY >
void moveTo (TX x, TY y)
 Move Polyline to new origin. More...
 
template<typename T1 >
void moveTo (const Point2d_< T1 > &new_org)
 Move Polyline to new origin, given by new_org. More...
 
template<typename CONT , typename std::enable_if< trait::IsContainer< CONT >::value, CONT >::type * = nullptr>
void set (const CONT &vec)
 Set from vector/array/list of points (discards previous points) More...
 
template<typename FPT1 , typename FPT2 , typename FPT3 >
void setParallelogram (const Point2d_< FPT1 > &pt1, const Point2d_< FPT2 > &pt2, const Point2d_< FPT3 > &pt3)
 Build a parallelogram (4 points) from 3 points. More...
 
template<typename FPT2 >
void set (const FRect_< FPT2 > &rect)
 Set from FRect. More...
 
template<typename FPT2 , typename T >
std::pair< HOMOG2D_INUMTYPE, HOMOG2D_INUMTYPEset (FPT2 rad, T n)
 Build RCP (Regular Convex Polygon), and return distance between consecutive points. More...
 
Operators
template<typename PLT2 , typename FPT2 >
bool operator== (const PolylineBase< PLT2, FPT2 > &other) const
 
template<typename PLT2 , typename FPT2 >
bool operator!= (const PolylineBase< PLT2, FPT2 > &other) const
 
- Public Member Functions inherited from h2d::detail::Common< FPT >
std::pair< int, int > dsize () const
 Get data size expressed as number of bits for, respectively, mantissa and exponent. More...
 
Dtype dtype () const
 Get numerical data type as a Dtype value, can be stringified with h2d::getString(Dtype) More...
 
template<typename T >
constexpr bool isInside (const Common< T > &) const
 This function is a fallback for all sub-classes that do not provide such a method. More...
 
size_t size () const
 
- Public Member Functions inherited from h2d::rtp::Root
virtual ~Root ()
 

Friends

template<typename T1 , typename T2 >
std::ostream & h2d::base::operator<< (std::ostream &, const h2d::base::PolylineBase< T1, T2 > &)
 
template<typename T1 >
class h2d::Ellipse_
 
template<typename FPT1 , typename FPT2 >
CPolyline_< FPT1 > h2d::operator* (const h2d::Homogr_< FPT2 > &, const h2d::FRect_< FPT1 > &)
 
template<typename FPT1 , typename FPT2 , typename PLT2 >
auto h2d::operator* (const Homogr_< FPT2 > &, const base::PolylineBase< PLT2, FPT1 > &) -> base::PolylineBase< PLT2, FPT1 >
 
template<typename T1 , typename T2 >
class PolylineBase
 

Data access

std::vector< Point2d_< FPT > > & getPts ()
 Returns the points (reference) More...
 
const std::vector< Point2d_< FPT > > & getPts () const
 Returns the points (const reference) More...
 
std::vector< OSegment_< FPT > > getOSegs () const
 Returns (as a copy) the oriented segments of the polyline. More...
 
std::vector< Segment_< FPT > > getSegs () const
 Returns (as a copy) the segments of the polyline. More...
 
Point2d_< FPT > getPoint (size_t idx) const
 Returns one point of the polyline. More...
 
OSegment_< FPT > getOSegment (size_t idx) const
 Returns one oriented segment of the polyline. More...
 
Segment_< FPT > getSegment (size_t idx) const
 Returns one segment of the polyline. More...
 
CPolyline_< FPT > convexHull () const
 Return convex hull (member function implementation) More...
 

Detailed Description

template<typename PLT, typename FPT>
class h2d::base::PolylineBase< PLT, FPT >

Polyline, will be instanciated either as OPolyline_ (open polyline) or CPolyline_.

Warning
When closed, in order to be able to compare two objects describing the same structure but potentially in different order, the comparison operator will proceed a sorting.
The consequence is that when adding points, if you have done a comparison before, you might not add point after the one you thought!

template args:

Member Typedef Documentation

◆ FType

template<typename PLT, typename FPT>
using h2d::base::PolylineBase< PLT, FPT >::FType = FPT

◆ SType

template<typename PLT, typename FPT>
using h2d::base::PolylineBase< PLT, FPT >::SType = std::conditional<std::is_same_v<PLT,typ::IsClosed>,typ::T_CPol,typ::T_OPol>

Constructor & Destructor Documentation

◆ PolylineBase() [1/8]

template<typename PLT, typename FPT>
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( )
default

Default constructor.

◆ PolylineBase() [2/8]

template<typename PLT, typename FPT>
template<typename FPT2 >
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const FRect_< FPT2 > &  rect)
inline

Constructor from FRect. Enabled for "closed" type, disabled for "open" type.

6106  {
6107  static_assert( std::is_same_v<PLT,typ::IsClosed>, "cannot build an OPolyline object from a FRect");
6108  for( const auto& pt: rect.get4Pts() )
6109  _plinevec.push_back( pt );
6110  }
FRect rect
Definition: homog2d_test.cpp:4056
Point2d pt
Definition: homog2d_test.cpp:4052

◆ PolylineBase() [3/8]

template<typename PLT, typename FPT>
template<typename FPT2 >
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const Segment_< FPT2 > &  seg)
inline
6114  {
6115  const auto& ppts = seg.getPts();
6116  p_addPoint( ppts.first );
6117  p_addPoint( ppts.second );
6118  }
Segment seg
Definition: homog2d_test.cpp:4051

◆ PolylineBase() [4/8]

template<typename PLT, typename FPT>
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * = nullptr>
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const T &  vec)
inline

Constructor from a vector of points.

6129  {
6130  set( vec );
6131  }

◆ PolylineBase() [5/8]

template<typename PLT, typename FPT>
template<typename FPT2 , typename T >
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( FPT2  rad,
n 
)
inline

Constructor that builds a regular convex polygon of n points at a distance rad, centered at (0,0).

6136  {
6137  set( rad, n );
6138  }

◆ PolylineBase() [6/8]

template<typename PLT, typename FPT>
template<typename FPT2 >
constexpr h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const CPolyline_< FPT2 > &  other)
inline

Copy-Constructor from Closed Polyline.

6143  {
6144  static_assert(
6145  !(std::is_same<PLT,typ::IsOpen>::value),
6146  "Error, cannot build an Open Polyline from a closed one"
6147  );
6148  set( other._plinevec );
6149  }

◆ PolylineBase() [7/8]

template<typename PLT, typename FPT>
template<typename FPT2 >
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const OPolyline_< FPT2 > &  other)
inline

Copy-Constructor from Open Polyline.

6153  {
6154  set( other._plinevec );
6155  }

◆ PolylineBase() [8/8]

template<typename PLT, typename FPT>
template<typename BPT , bool CLKW, bool CLOSED>
h2d::base::PolylineBase< PLT, FPT >::PolylineBase ( const boost::geometry::model::polygon< BPT, CLKW, CLOSED > &  bgpol)
inline

Constructor from a boost geometry polygon, see misc/test_files/bg_test_1.cpp.

Note
Only imports the "outer" envelope, homog2d does not handle polygons with holes

Requirements: the Boost polygon must have 2-cartesian coordinates points, either bg::model::point or bg::model::d2::point_xy but the underlying numerical type is free.

Note
At present, the 3th template parameter (bool) (Closed or Open) is ignored, because it is unclear how this relates to the actual fact that last point is equal to first point.
Todo:
20230216: add some checking that the type BPT needs to fit certain requirements (must have 2-dimensions, and use cartesian coordinates). Maybe we should add some Sfinae to check this.
Parameters
bgpolBoost Point Type (either bg::model::point or bg::model::d2::point_xy) this one is ignored here true: closed, false: open input boost geometry polygon
6179  {
6180  const auto& outer = bgpol.outer();
6181  bool isClosed = false;
6182  auto ptf = outer.front();
6183  auto ptb = outer.back();
6184  Point2d_<HOMOG2D_INUMTYPE> pt_front( boost::geometry::get<0>(ptf), boost::geometry::get<1>(ptf) );
6185  Point2d_<HOMOG2D_INUMTYPE> pt_back( boost::geometry::get<0>(ptb), boost::geometry::get<1>(ptb) );
6186 /*
6187 this should work !!! (but doesn't...)
6188  Point2d_<HOMOG2D_INUMTYPE> pt_front( outer.front() );
6189  Point2d_<HOMOG2D_INUMTYPE> pt_back( outer.back() );
6190 */
6191  if( pt_front == pt_back ) // means it's closed
6192  isClosed = true;
6193 
6194  if( isClosed && std::is_same_v<PLT,typ::IsOpen> ) // cannot build an open polyline from a closed one
6195  HOMOG2D_THROW_ERROR_1( "unable to convert a closed boost::polygon into an OPolyline" );
6196 
6197  _plinevec.reserve( outer.size() - isClosed );
6198  for( auto it=outer.begin(); it!=outer.end()-isClosed; it++ )
6199  {
6200  const auto& bgpt = *it;
6201  _plinevec.emplace_back(
6202  Point2d_<FPT>( boost::geometry::get<0>(bgpt), boost::geometry::get<1>(bgpt) )
6203  );
6204  }
6205  }
constexpr bool isClosed() const
Definition: homog2d.hpp:6217
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181

Member Function Documentation

◆ area()

template<typename PLT , typename FPT >
HOMOG2D_INUMTYPE h2d::base::PolylineBase< PLT, FPT >::area ( ) const
virtual

Returns area of polygon (computed only if necessary)

Implements h2d::rtp::Root.

7486 {
7487  if( !isSimple() ) // implies that is both closed and has no intersections
7488  return 0.;
7489 
7490  if( _attribs._area.isBad() )
7491  _attribs._area.set( homog2d_abs( p_ComputeSignedArea() ) );
7492  return _attribs._area.value();
7493 }
void set(T v)
Definition: homog2d.hpp:5865
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
#define homog2d_abs
Definition: homog2d.hpp:69
bool isBad() const
Definition: homog2d.hpp:5872
priv::ValueFlag< HOMOG2D_INUMTYPE > _area
Definition: homog2d.hpp:5881
T value() const
Definition: homog2d.hpp:5870
Here is the caller graph for this function:

◆ centroid()

template<typename PLT, typename FPT>
Point2d_< HOMOG2D_INUMTYPE > h2d::base::base::PolylineBase::centroid ( ) const

Compute centroid of polygon.

ref: https://en.wikipedia.org/wiki/Centroid#Of_a_polygon

Warning
: centroid CAN be outside of polygon!
7523 {
7524  if( !isSimple() )
7525  HOMOG2D_THROW_ERROR_1( "unable, Polyline object is not simple" );
7526 
7527  if( _attribs._centroid.isBad() )
7528  {
7529  HOMOG2D_INUMTYPE cx = 0.;
7530  HOMOG2D_INUMTYPE cy = 0.;
7531  for( size_t i=0; i<size(); i++ )
7532  {
7533  auto j = (i == size()-1 ? 0 : i+1);
7534  const auto& pt1 = _plinevec[i];
7535  const auto& pt2 = _plinevec[j];
7536  auto x1 = pt1.getX();
7537  auto x2 = pt2.getX();
7538  auto y1 = pt1.getY();
7539  auto y2 = pt2.getY();
7540 
7541  auto prod = x1*y2 - x2*y1;
7542  cx += (x1+x2) * prod;
7543  cy += (y1+y2) * prod;
7544  }
7545  auto signedArea = p_ComputeSignedArea();
7546  cx /= (6. * signedArea);
7547  cy /= (6. * signedArea);
7548 
7549  auto c = Point2d_<HOMOG2D_INUMTYPE>( cx, cy );
7550  _attribs._centroid.set( c );
7551  }
7552  return _attribs._centroid.value();
7553 }
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
priv::ValueFlag< Point2d_< HOMOG2D_INUMTYPE > > _centroid
Definition: homog2d.hpp:5883
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Here is the caller graph for this function:

◆ clear()

template<typename PLT, typename FPT>
void h2d::base::PolylineBase< PLT, FPT >::clear ( )
inline

Clear all (does not change the "open/close" status).

6380  {
6381  _plinevec.clear();
6382  _plIsNormalized=false;
6383  _attribs.setBad();
6384  }
void setBad()
Definition: homog2d.hpp:5885

◆ convexHull()

template<typename CT , typename FPT >
CPolyline_< FPT > h2d::base::PolylineBase< CT, FPT >::convexHull ( ) const

Return convex hull (member function implementation)

11628 {
11629  return h2d::convexHull( *this );
11630 }
CPolyline_< FPT > convexHull(const base::PolylineBase< CT, FPT > &input)
Compute Convex Hull of a Polyline (free function)
Definition: homog2d.hpp:11540
Here is the caller graph for this function:

◆ draw() [1/2]

template<typename PLT , typename FPT >
void h2d::base::PolylineBase< PLT, FPT >::draw ( img::Image< img::SvgImage > &  im,
img::DrawParams  dp = img::DrawParams() 
) const
virtual

Draw Polyline (SVG implementation)

Note
To show the points index, we don't use the svg "marker-start/marker-mid/marker-end" syntax so that the dots always have the same color as the segments
Todo:
20240215 Why don't we use the drawText() function ?

Implements h2d::rtp::Root.

12307 {
12308  if( size() < 2 ) // nothing to draw
12309  return;
12310 
12311  if( dp._dpValues._showIndex || dp._dpValues._showPoints )
12312  im.getReal()._svgString << "<g>\n";
12313 
12314  im.getReal()._svgString << '<' << (isClosed() ? "polygon" : "polyline")
12315  << " stroke=\""
12316  << dp.getSvgRgbColor()
12317  << "\" stroke-width=\"" << dp._dpValues._lineThickness << "\" ";
12318  if( !dp.holdsFill() )
12319  im.getReal()._svgString << "fill=\"none\" ";
12320  im.getReal()._svgString << dp.getAttrString()
12321  << "points=\"";
12322  for( const auto& pt: getPts() )
12323  im.getReal()._svgString << pt.getX() << ',' << pt.getY() << ' ';
12324  im.getReal()._svgString << "\"/>\n";
12325 
12327  if( dp._dpValues._showIndex )
12328  {
12329  im.getReal()._svgString << "<g>\n";
12330  for( size_t i=0; i<size(); i++ )
12331  {
12332  auto pt = getPoint(i);
12333  im.getReal()._svgString << "<text x=\""
12334  << (int)pt.getX()
12335  << "\" y=\""
12336  << (int)pt.getY()
12337  << "\" class=\"txt1\">"
12338  << i
12339  << "</text>\n";
12340  }
12341  im.getReal()._svgString << "</g>\n";
12342  }
12343 
12344  if( dp._dpValues._showPoints )
12345  {
12346  im.getReal()._svgString << "<g>\n";
12347  for( size_t i=0; i<size(); i++ )
12348  getPoint(i).draw( im, dp );
12349  im.getReal()._svgString << "</g>\n";
12350  }
12351 
12352  if( dp._dpValues._showAngles )
12353  {
12354  auto osegs = getOSegs();
12355 // std::cout << "osegs size=" << osegs.size() << "\n";
12356 
12357  const auto& pts = getPts();
12358  for( size_t i=0; i<osegs.size()-1; i++ )
12359  {
12360  auto seg1 = osegs[i];
12361  auto seg2 = osegs[i+1];
12362  auto angle = getAngle( seg1, seg2 );
12363 // std::cout << "angle " << i << "=" << angle*180/3.1415 << "\n";
12364  drawText( im, std::to_string(angle * 180./M_PI), pts[i+1] );
12365  }
12366  }
12367 
12368  if( dp._dpValues._showIndex || dp._dpValues._showPoints )
12369  im.getReal()._svgString << "</g>\n";
12370 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
void drawText(img::Image< U > &im, std::string str, Point2d_< FPT > pt, img::DrawParams dp=img::DrawParams())
Free function, draws text str at position pt.
Definition: homog2d.hpp:11264
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9208
#define M_PI
Definition: homog2d.hpp:235
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10997
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
img::Image< img::SvgImage > im(300, 400)
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Point2d pt
Definition: homog2d_test.cpp:4052
Here is the caller graph for this function:

◆ draw() [2/2]

template<typename PLT , typename FPT >
void h2d::base::PolylineBase< PLT, FPT >::draw ( img::Image< cv::Mat > &  im,
img::DrawParams  dp = img::DrawParams() 
) const
virtual

Draw PolylineBase (Opencv implementation)

Implements h2d::rtp::Root.

11954 {
11955  if( size() < 2 ) // nothing to draw
11956  return;
11957 
11958  for( size_t i=0; i<nbSegs(); i++ )
11959  getSegment(i).draw( im, dp );
11960 
11961  if( dp._dpValues._showPoints )
11962  {
11963  auto newPointStyle = dp._dpValues.nextPointStyle();
11964  getPoint(0).draw( im, dp.setColor(10,10,10).setPointStyle( newPointStyle ) );
11965  }
11966 
11967  if( dp._dpValues._showIndex )
11968  for( size_t i=0; i<size(); i++ )
11969  {
11970  auto pt = getPoint(i);
11971  cv::putText(
11972  im.getReal(),
11973  std::to_string(i),
11974  pt.getCvPti(),
11975  0,
11976  0.6,
11977  cv::Scalar( 20,20,20 ),
11978  2
11979  );
11980  }
11981 
11982  if( dp._dpValues._showAngles )
11983  {
11984  auto osegs = getOSegs();
11985 // std::cout << "osegs size=" << osegs.size() << "\n";
11986 
11987  const auto& pts = getPts();
11988  for( size_t i=0; i<osegs.size()-1; i++ )
11989  {
11990  auto seg1 = osegs[i];
11991  auto seg2 = osegs[i+1];
11992  auto angle = getAngle( seg1, seg2 );
11993 // std::cout << "angle " << i << "=" << angle*180/3.1415 << "\n";
11994  drawText( im, std::to_string(angle * 180./M_PI), pts[i+1] );
11995  }
11996  if( isClosed() )
11997  {
11998  auto seg1 = osegs.back();
11999  auto seg2 = osegs.front();
12000  auto angle = getAngle( seg1, seg2 );
12001 // std::cout << "final angle " << "=" << angle*180/3.1415 << "\n";
12002  drawText( im, std::to_string(angle * 180./M_PI), pts[0] );
12003  }
12004  }
12005 }
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 drawText(img::Image< U > &im, std::string str, Point2d_< FPT > pt, img::DrawParams dp=img::DrawParams())
Free function, draws text str at position pt.
Definition: homog2d.hpp:11264
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9208
#define M_PI
Definition: homog2d.hpp:235
Segment_< FPT > getSegment(size_t idx) const
Returns one segment of the polyline.
Definition: homog2d.hpp:6366
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10997
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
img::Image< img::SvgImage > im(300, 400)
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Point2d pt
Definition: homog2d_test.cpp:4052

◆ getBB()

template<typename PLT, typename FPT>
auto h2d::base::PolylineBase< PLT, FPT >::getBB ( ) const
inline

Returns Bounding Box of Polyline.

6231  {
6232  HOMOG2D_START;
6233 #ifndef HOMOG2D_NOCHECKS
6234  if( size() < 2 )
6235  HOMOG2D_THROW_ERROR_1( "cannot compute bounding box of empty Polyline" );
6236 #endif
6237  auto ppts = priv::getBB_Points( getPts() );
6238 #ifndef HOMOG2D_NOCHECKS
6239  if( shareCommonCoord( ppts.first, ppts.second ) )
6240  HOMOG2D_THROW_ERROR_1( "unable, points share common coordinate" );
6241 #endif
6242  return FRect_<HOMOG2D_INUMTYPE>( ppts );
6243  }
PointPair_< typename T::value_type::FType > getBB_Points(const T &vpts)
Returns the bounding box of points in vector/list/array of points vpts (free function) ...
Definition: homog2d.hpp:5907
#define HOMOG2D_START
Definition: homog2d.hpp:106
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
bool shareCommonCoord(const std::pair< Point2d_< FPT1 >, Point2d_< FPT2 >> &ppts)
Returns true if one of the points share a common coordinate (thus making them unable to define a boun...
Definition: homog2d.hpp:1336
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Here is the caller graph for this function:

◆ getBisectorLines()

template<typename PLT, typename FPT>
std::vector<Line2d_<HOMOG2D_INUMTYPE> > h2d::base::PolylineBase< PLT, FPT >::getBisectorLines ( ) const
inline
6654  {
6655  return h2d::getBisectorLines( *this );
6656  }
std::vector< Line2d_< HOMOG2D_INUMTYPE > > getBisectorLines(const base::PolylineBase< PLT, FPT > &)
Returns bisector lines of a Polyline.
Definition: homog2d.hpp:9986

◆ getBmPoint()

template<typename PLT , typename FPT >
Point2d_< FPT > h2d::base::PolylineBase< PLT, FPT >::getBmPoint ( ) const

Return Bottom-most point of Polyline.

7126 {
7127  return h2d::getBmPoint( *this );
7128 }
auto getBmPoint(const T &t)
Return Bottom-most point of container holding points.
Definition: homog2d.hpp:6919
Here is the caller graph for this function:

◆ getExtremePoint()

template<typename PLT , typename FPT >
Point2d_< FPT > h2d::base::PolylineBase< PLT, FPT >::getExtremePoint ( CardDir  dir) const

Get Top-most / Bottom-most / Left-most / Right-most point.

7118 {
7119  return getExtremePoint( dir, *this );
7120 }
Point2d_< FPT > getExtremePoint(CardDir) const
Get Top-most / Bottom-most / Left-most / Right-most point.
Definition: homog2d.hpp:7117

◆ getLmPoint()

template<typename PLT , typename FPT >
Point2d_< FPT > h2d::base::PolylineBase< PLT, FPT >::getLmPoint ( ) const

Return Left-most point of Polyline.

7142 {
7143  return h2d::getLmPoint( *this );
7144 }
auto getLmPoint(const T &t)
Return Left-most point of container as a pair holding:
Definition: homog2d.hpp:6991
Here is the caller graph for this function:

◆ getOffsetPoly()

template<typename PLT , typename FPT >
template<typename T >
PolylineBase< typ::IsClosed, FPT > h2d::base::PolylineBase< PLT, FPT >::getOffsetPoly ( dist,
OffsetPolyParams  params = OffsetPolyParams{} 
) const

Return an "offsetted" closed polyline, requires simple polygon (CPolyline AND no crossings) as input.

On failure (for whatever reason), will return an empty CPolyline

  • If dist>0, returns the polyline "outside" the source one
  • If dist<0, returns the polyline "inside" the source one
6678 {
6680  auto dist0 = (HOMOG2D_INUMTYPE)dist; // casting
6681 
6682  bool valid = true;
6684  {
6685  HOMOG2D_LOG_WARNING( "Failure, distance value is null, returning empty CPolyline" );
6686  valid = false;
6687  }
6688  if( size()<3 )
6689  {
6690  HOMOG2D_LOG_WARNING( "Failure, computing offsetted Polyline requires at least 3 points, returning empty CPolyline" );
6691  valid = false;
6692  }
6693  if( !isSimple() )
6694  {
6695  HOMOG2D_LOG_WARNING( "Failure, Polyline is not a polygon, returning empty CPolyline" );
6696  valid = false;
6697  }
6698  if( !valid )
6699  return PolylineBase<typ::IsClosed,FPT>();
6700 
6701  p_normalizePoly();
6702 
6703  size_t current = 0;
6704 // bool paraLines = false;
6705 
6706  std::vector<Point2d_<FPT>> v_out;
6707  auto osegs = getOSegs();
6708  auto oseg1 = osegs.at(current);
6709  do
6710  {
6711  auto next = (current==size()-1 ? 0 : current+1);
6712 
6713  auto pt1 = getPoint(next);
6714 
6715  auto oseg2 = osegs.at(next);
6716 
6717  auto psegs1 = oseg1.getParallelSegs(homog2d_abs(dist0));
6718  auto psegs2 = oseg2.getParallelSegs(homog2d_abs(dist0));
6719 
6720  auto pseg1 = &psegs1.first;
6721  auto pseg2 = &psegs2.first;
6722  if( dist < 0 )
6723  {
6724  pseg1 = &psegs1.second;
6725  pseg2 = &psegs2.second;
6726  }
6727 
6728  auto li1 = pseg1->getLine();
6729  auto li2 = pseg2->getLine();
6730  if( !areParallel(li1,li2) )
6731  {
6732  auto pt_int = li1 * li2;
6733  if( !params._angleSplit || getAngle(oseg1,oseg2)>0 || dist < 0 )
6734  {
6735  v_out.push_back( pt_int ); // add point intersection of the two lines
6736  }
6737  else
6738  {
6739  auto oseg = OSegment_<HOMOG2D_INUMTYPE>( pt1, pt_int );
6740  auto dist_cut = std::min( oseg.length(), dist0 );
6741 
6742  auto pt_cut = oseg.getPointAt( dist_cut );
6743  auto oli = oseg.getLine().getOrthogLine( pt_cut );
6744 
6745  auto pt_cut1 = oli * li1;
6746  auto pt_cut2 = oli * li2;
6747 
6748  v_out.push_back( pt_cut1 );
6749  if( pt_cut1 != pt_cut2 ) // so we don't add two identical pts (in case they were computed as such)
6750  v_out.push_back( pt_cut2 );
6751  }
6752  }
6753 // else
6754 // std::cout << "parallel!\n";
6755 
6756  current++;
6757  oseg1 = oseg2;
6758  }
6759  while( current<size() ); //&& !paraLines );
6760 
6761  return PolylineBase<typ::IsClosed,FPT>( v_out );
6762 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1229
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9208
#define homog2d_abs
Definition: homog2d.hpp:69
#define HOMOG2D_LOG_WARNING(a)
Definition: homog2d.hpp:151
HOMOG2D_INUMTYPE dist(const Point2d_< FPT1 > &pt1, const Point2d_< FPT2 > &pt2)
Free function, distance between points.
Definition: homog2d.hpp:9851
bool areParallel(const T1 &t1, const T2 &t2)
Returns true is lines (or segments) are parallel.
Definition: homog2d.hpp:4626
std::vector< OSegment_< FPT > > getOSegs() const
Returns (as a copy) the oriented segments of the polyline.
Definition: homog2d.hpp:6312
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215

◆ getOSegment()

template<typename PLT, typename FPT>
OSegment_<FPT> h2d::base::PolylineBase< PLT, FPT >::getOSegment ( size_t  idx) const
inline

Returns one oriented segment of the polyline.

6358  {
6359  return impl_getSegment( idx, OSegment_<FPT>() );
6360  }
Here is the caller graph for this function:

◆ getOSegs()

template<typename PLT, typename FPT>
std::vector<OSegment_<FPT> > h2d::base::PolylineBase< PLT, FPT >::getOSegs ( ) const
inline

Returns (as a copy) the oriented segments of the polyline.

6313  {
6314  return priv::p_getSegs( *this, OSegment_<FPT>() );
6315  }
std::vector< ST > p_getSegs(const base::PolylineBase< PLT, FPT > &pl, const ST &)
Private helper function for base::PolylineBase::getSegs() and base::PolylineBase::getOSegs() ...
Definition: homog2d.hpp:6000
Here is the caller graph for this function:

◆ getPoint()

template<typename PLT, typename FPT>
Point2d_<FPT> h2d::base::PolylineBase< PLT, FPT >::getPoint ( size_t  idx) const
inline

Returns one point of the polyline.

6325  {
6326 #ifndef HOMOG2D_NOCHECKS
6327  if( idx >= size() )
6328  HOMOG2D_THROW_ERROR_1( "requesting point " << idx
6329  << ", only has " << size()
6330  );
6331 #endif
6332  return _plinevec[idx];
6333  }
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Here is the caller graph for this function:

◆ getPts() [1/2]

template<typename PLT, typename FPT>
std::vector<Point2d_<FPT> >& h2d::base::PolylineBase< PLT, FPT >::getPts ( )
inline

Returns the points (reference)

6300  {
6301  _attribs.setBad(); // because we send the non-const reference
6302  _plIsNormalized=false;
6303  return _plinevec;
6304  }
void setBad()
Definition: homog2d.hpp:5885
Here is the caller graph for this function:

◆ getPts() [2/2]

template<typename PLT, typename FPT>
const std::vector<Point2d_<FPT> >& h2d::base::PolylineBase< PLT, FPT >::getPts ( ) const
inline

Returns the points (const reference)

6307  {
6308  return _plinevec;
6309  }

◆ getRmPoint()

template<typename PLT , typename FPT >
Point2d_< FPT > h2d::base::PolylineBase< PLT, FPT >::getRmPoint ( ) const

Return Right-most point of Polyline.

7150 {
7151  return h2d::getRmPoint( *this );
7152 }
auto getRmPoint(const T &t)
Return Right-most point of container holding points.
Definition: homog2d.hpp:7032
Here is the caller graph for this function:

◆ getSegment()

template<typename PLT, typename FPT>
Segment_<FPT> h2d::base::PolylineBase< PLT, FPT >::getSegment ( size_t  idx) const
inline

Returns one segment of the polyline.

Segment n is the one between point n and point n+1

6367  {
6368  return impl_getSegment( idx, Segment_<FPT>() );
6369  }

◆ getSegs()

template<typename PLT, typename FPT>
std::vector<Segment_<FPT> > h2d::base::PolylineBase< PLT, FPT >::getSegs ( ) const
inline

Returns (as a copy) the segments of the polyline.

6319  {
6320  return priv::p_getSegs( *this, Segment_<FPT>() );
6321  }
std::vector< ST > p_getSegs(const base::PolylineBase< PLT, FPT > &pl, const ST &)
Private helper function for base::PolylineBase::getSegs() and base::PolylineBase::getOSegs() ...
Definition: homog2d.hpp:6000
Here is the caller graph for this function:

◆ getTmPoint()

template<typename PLT , typename FPT >
Point2d_< FPT > h2d::base::PolylineBase< PLT, FPT >::getTmPoint ( ) const

Return Top-most point of Polyline.

7134 {
7135  return h2d::getTmPoint( *this );
7136 }
auto getTmPoint(const T &t)
Return Top-most point of container.
Definition: homog2d.hpp:6944
Here is the caller graph for this function:

◆ intersects()

template<typename PLT, typename FPT>
template<typename T , typename std::enable_if< trait::IsShape< T >::value, T >::type * = nullptr>
detail::IntersectM<FPT> h2d::base::PolylineBase< PLT, FPT >::intersects ( const T &  other) const
inline

Polyline intersection with Line, Segment, FRect, Circle.

6573  {
6574  detail::IntersectM<FPT> out;
6575  for( const auto& pseg: getSegs() )
6576  {
6577  auto inters = pseg.intersects( other );
6578  if( inters() )
6579  out.add( inters.get() );
6580  }
6581  return out;
6582  }
std::vector< Segment_< FPT > > getSegs() const
Returns (as a copy) the segments of the polyline.
Definition: homog2d.hpp:6318
Here is the caller graph for this function:

◆ isClosed()

template<typename PLT, typename FPT>
constexpr bool h2d::base::PolylineBase< PLT, FPT >::isClosed ( ) const
inline
6218  {
6219  if constexpr( std::is_same_v<PLT,typ::IsClosed> )
6220  return true;
6221  else
6222  return false;
6223  }
Here is the caller graph for this function:

◆ isConvex()

template<typename PLT , typename FPT >
bool h2d::base::PolylineBase< PLT, FPT >::isConvex ( ) const

Returns true if polygon is convex.

This implies that:

Todo:
20221120: as points are homogeneous, the cross product can probably be computed in a different way (quicker? simpler?). Need to check this.
Todo:
20250127: use crossProduct free function with base::SegVec args
7435 {
7436  if( !isSimple() )
7437  return false;
7438 
7439  int8_t sign = 0;
7440  const auto& vpts = getPts();
7441  if( vpts.size() == 3 ) // 3 pts => always convex
7442  return true;
7443 
7444  for( size_t i=0; i<vpts.size(); i++ )
7445  {
7446  const auto& pt0 = vpts[ i==0?vpts.size()-1:i-1 ];
7447  const auto& pt1 = vpts[ i ];
7448  const auto& pt2 = vpts[ i==vpts.size()-1?0:i+1 ];
7449  auto dx1 = pt1.getX() - pt0.getX();
7450  auto dy1 = pt1.getY() - pt0.getY();
7451 
7452  auto dx2 = pt2.getX() - pt1.getX();
7453  auto dy2 = pt2.getY() - pt1.getY();
7454 
7455  auto crossproduct = dx1*dy2 - dy1*dx2;
7456  if( sign == 0 ) // initial sign value
7457  sign = (crossproduct>0 ? +1 : -1);
7458  else
7459  if (sign != (crossproduct>0 ? +1 : -1) )
7460  return false;
7461  }
7462  return true;
7463 }
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7385
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
int sign(T val)
Get sign of value.
Definition: homog2d.hpp:3567
Here is the caller graph for this function:

◆ isInside() [1/2]

template<typename PLT, typename FPT>
template<typename T , typename std::enable_if<(trait::HasArea< T >::value &&!trait::PolIsClosed< T >::value), T >::type * = nullptr>
bool h2d::base::PolylineBase< PLT, FPT >::isInside ( const T &  prim) const
inline

Polyline isInside other primitive.

Sfinae should resolve for T=Circle,FRect,Ellipse but not for CPolyline

6601  {
6602  HOMOG2D_START;
6603  if( size() == 0 )
6604  return false;
6605  for( const auto& pt: getPts() )
6606  if( !pt.isInside( prim ) )
6607  return false;
6608  return true;
6609  }
#define HOMOG2D_START
Definition: homog2d.hpp:106
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Point2d pt
Definition: homog2d_test.cpp:4052
Here is the caller graph for this function:

◆ isInside() [2/2]

template<typename PLT, typename FPT>
template<typename T , typename std::enable_if< trait::PolIsClosed< T >::value, T >::type * = nullptr>
bool h2d::base::PolylineBase< PLT, FPT >::isInside ( const T &  cpol) const
inline

Polyline isInside other CPolyline.

Sfinae should resolve ONLY for CPolyline

6623  {
6624  HOMOG2D_START;
6625  if( size() == 0 )
6626  return false;
6627  for( const auto& pt: getPts() )
6628  if( !pt.isInside( cpol ) )
6629  return false;
6630  if( intersects(cpol)() )
6631  return false;
6632  return true;
6633  }
#define HOMOG2D_START
Definition: homog2d.hpp:106
detail::IntersectM< FPT > intersects(const T &other) const
Polyline intersection with Line, Segment, FRect, Circle.
Definition: homog2d.hpp:6572
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
CPolyline cpol
Definition: homog2d_test.cpp:4048
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Point2d pt
Definition: homog2d_test.cpp:4052

◆ isSimple()

template<typename PLT , typename FPT >
bool h2d::base::PolylineBase< PLT, FPT >::isSimple ( ) const

Returns true if object is a polygon (closed, and no segment crossing)

7386 {
7387  if( size()<3 ) // needs at least 3 points to be a polygon
7388  return false;
7389  if constexpr( std::is_same_v<PLT,typ::IsOpen> ) // If open, then not a polygon
7390  return false;
7391  else // If closed, we need to check for crossings
7392  {
7393  if( _attribs._isSimplePolyg.isBad() )
7394  {
7395  auto nbs = nbSegs();
7396  size_t i=0;
7397  bool notDone = true;
7398  bool hasIntersections = false;
7399  do
7400  {
7401  auto seg1 = getSegment(i);
7402  auto lastone = i==0?nbs-1:nbs;
7403  for( auto j=i+2; j<lastone; j++ )
7404  if( getSegment(j).intersects(seg1)() )
7405  {
7406  notDone = false;
7407  hasIntersections = true;
7408  break;
7409  }
7410  i++;
7411  }
7412  while( i<nbs && notDone );
7413  _attribs._isSimplePolyg.set( !hasIntersections );
7414  }
7415  return _attribs._isSimplePolyg.value();
7416  }
7417 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6249
void set(T v)
Definition: homog2d.hpp:5865
bool isBad() const
Definition: homog2d.hpp:5872
Segment_< FPT > getSegment(size_t idx) const
Returns one segment of the polyline.
Definition: homog2d.hpp:6366
detail::IntersectM< FPT > intersects(const T &other) const
Polyline intersection with Line, Segment, FRect, Circle.
Definition: homog2d.hpp:6572
priv::ValueFlag< bool > _isSimplePolyg
Definition: homog2d.hpp:5882
T value() const
Definition: homog2d.hpp:5870
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Here is the caller graph for this function:

◆ length()

template<typename PLT , typename FPT >
HOMOG2D_INUMTYPE h2d::base::PolylineBase< PLT, FPT >::length ( ) const
virtual

Returns length of Polyline.

Implements h2d::rtp::Root.

7470 {
7471  if( _attribs._length.isBad() )
7472  {
7473  HOMOG2D_INUMTYPE sum = 0.;
7474  for( const auto& seg: getSegs() )
7475  sum += static_cast<HOMOG2D_INUMTYPE>( seg.length() );
7476  _attribs._length.set( sum );
7477  }
7478  return _attribs._length.value();
7479 }
std::vector< Segment_< FPT > > getSegs() const
Returns (as a copy) the segments of the polyline.
Definition: homog2d.hpp:6318
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
void set(T v)
Definition: homog2d.hpp:5865
Segment seg
Definition: homog2d_test.cpp:4051
bool isBad() const
Definition: homog2d.hpp:5872
priv::ValueFlag< HOMOG2D_INUMTYPE > _length
Definition: homog2d.hpp:5880
T value() const
Definition: homog2d.hpp:5870
Here is the caller graph for this function:

◆ minimize()

template<typename PLT, typename FPT>
void h2d::base::PolylineBase< PLT, FPT >::minimize ( )
inline

Miminize the PolylineBase: remove all points that lie in the middle of two segments with same angle.

For example, if we have the following points ("Open" polyline): (0,0)-(1,0)-(2,0)
This will be replaced by: (0,0)–(2,0)

Note
We cannot use the Segment_::getAngle() function because it returns a value in [0,PI/2], so we would'nt be able to detect a segment going at 180° of the previous one.
Todo:
20230217: implement these:
6407  {
6408  if( size()<3 )
6409  return;
6410  impl_minimizePL( detail::PlHelper<PLT>() );
6411  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215

◆ moveTo() [1/2]

template<typename PLT, typename FPT>
template<typename TX , typename TY >
void h2d::base::PolylineBase< PLT, FPT >::moveTo ( TX  x,
TY  y 
)
inline

Move Polyline to new origin.

6433  {
6436  moveTo( Point2d_<FPT>(x,y) );
6437  }
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
void moveTo(TX x, TY y)
Move Polyline to new origin.
Definition: homog2d.hpp:6432

◆ moveTo() [2/2]

template<typename PLT, typename FPT>
template<typename T1 >
void h2d::base::PolylineBase< PLT, FPT >::moveTo ( const Point2d_< T1 > &  new_org)
inline

Move Polyline to new origin, given by new_org.

Warning
The polygon origin is NOT its center but the point No 0!
6445  {
6446  if( size() == 0 )
6447  HOMOG2D_THROW_ERROR_1( "Invalid call, Polyline is empty" );
6448  auto dx = new_org.getX() - getPoint(0).getX();
6449  auto dy = new_org.getY() - getPoint(0).getY();
6450  for( auto& pt: _plinevec )
6451  pt.translate( dx, dy );
6452  }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Point2d pt
Definition: homog2d_test.cpp:4052

◆ nbSegs()

template<typename PLT, typename FPT>
size_t h2d::base::PolylineBase< PLT, FPT >::nbSegs ( ) const
inline

Returns the number of segments. If "closed",.

the last segment (going from last to first point) is counted

6250  {
6251  if( size() < 2 )
6252  return 0;
6253  if constexpr( std::is_same_v<PLT,typ::IsClosed> )
6254  return size();
6255  else
6256  return size() - 1;
6257  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215
Here is the caller graph for this function:

◆ operator!=()

template<typename PLT, typename FPT>
template<typename PLT2 , typename FPT2 >
bool h2d::base::PolylineBase< PLT, FPT >::operator!= ( const PolylineBase< PLT2, FPT2 > &  other) const
inline
6559  {
6560  return !( *this == other );
6561  }

◆ operator==()

template<typename PLT, typename FPT>
template<typename PLT2 , typename FPT2 >
bool h2d::base::PolylineBase< PLT, FPT >::operator== ( const PolylineBase< PLT2, FPT2 > &  other) const
inline
6538  {
6539  if constexpr( std::is_same_v<PLT,PLT2> )
6540  {
6541  if( size() != other.size() ) // for quick exit
6542  return false;
6543 
6544  p_normalizePoly();
6545  other.p_normalizePoly();
6546 
6547  auto it = other._plinevec.begin();
6548  for( const auto& elem: _plinevec )
6549  if( *it++ != elem )
6550  return false;
6551  return true;
6552  }
6553  else
6554  return false;
6555  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6215

◆ rotate() [1/2]

template<typename PLT , typename FPT >
template<typename FPT2 >
void h2d::base::PolylineBase< PLT, FPT >::rotate ( Rotate  rot,
const Point2d_< FPT2 > &  refpt 
)

Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt.

For an arbitrary angle alpha (rad.), you can write:

auto poly2 = Homogr(alpha) * poly;
See also
PolylineBase<PLT,FPT>::rotate( Rotate )
7270 {
7271  translate( -refpt.getX(), -refpt.getY() );
7272  this->rotate( rot );
7273  translate( refpt.getX(), refpt.getY() );
7274 }
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6415
void rotate(Rotate, const Point2d_< FPT2 > &)
Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt.
Definition: homog2d.hpp:7269
Here is the caller graph for this function:

◆ rotate() [2/2]

template<typename PLT , typename FPT >
void h2d::base::PolylineBase< PLT, FPT >::rotate ( Rotate  rot)

Rotates the polyline by either 90°, 180°, 270° (-90°) at point (0,0)

For an arbitrary angle alpha (rad.), you can write:

auto poly2 = Homogr(alpha) * poly;
See also
PolylineBase<PLT,FPT>::rotate( Rotate, const Point2d_<FPT2>& )
7288 {
7289  switch( rot )
7290  {
7291  case Rotate::CCW:
7292  for( auto& pt: getPts() )
7293  pt.set( -pt.getY(), +pt.getX() );
7294  break;
7295  case Rotate::CW:
7296  for( auto& pt: getPts() )
7297  pt.set( +pt.getY(), -pt.getX() );
7298  break;
7299  case Rotate::Full:
7300  for( auto& pt: getPts() )
7301  pt.set( -pt.getX(), -pt.getY() );
7302  break;
7303  case Rotate::VMirror:
7304  for( auto& pt: getPts() )
7305  pt.set( -pt.getX(), pt.getY() );
7306  break;
7307  case Rotate::HMirror:
7308  for( auto& pt: getPts() )
7309  pt.set( pt.getX(), -pt.getY() );
7310  break;
7311 
7312  default: assert(0);
7313  }
7314 }
180° rotation
ClockWise rotation.
horizontal symmetry
Counter ClockWise rotation.
vertical symmetry
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6299
Point2d pt
Definition: homog2d_test.cpp:4052

◆ set() [1/3]

template<typename PLT, typename FPT>
template<typename CONT , typename std::enable_if< trait::IsContainer< CONT >::value, CONT >::type * = nullptr>
void h2d::base::PolylineBase< PLT, FPT >::set ( const CONT &  vec)
inline

Set from vector/array/list of points (discards previous points)

  • nb of elements must be 0 or 2 or more
6466  {
6467 #ifndef HOMOG2D_NOCHECKS
6468  if( vec.size() == 1 )
6469  HOMOG2D_THROW_ERROR_1( "Invalid: number of points must be 0, 2 or more" );
6470  if( vec.size() > 1 )
6471  p_checkInputData( vec );
6472 #endif
6473  _attribs.setBad();
6474  _plIsNormalized=false;
6475  _plinevec.resize( vec.size() );
6476  auto it = std::begin( _plinevec );
6477  for( const auto& pt: vec ) // copying one by one will allow
6478  *it++ = pt; // type conversions (std::copy implies same FP type)
6479  }
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
void setBad()
Definition: homog2d.hpp:5885
Point2d pt
Definition: homog2d_test.cpp:4052
Here is the caller graph for this function:

◆ set() [2/3]

template<typename PLT, typename FPT>
template<typename FPT2 >
void h2d::base::PolylineBase< PLT, FPT >::set ( const FRect_< FPT2 > &  rect)
inline

Set from FRect.

6491  {
6492  static_assert( std::is_same_v<PLT,typ::IsClosed>, "Invalid: cannot set a OPolyline from a FRect" );
6493 
6494  CPolyline_<FPT> tmp(rect);
6495  std::swap( *this, tmp );
6496  }
FRect rect
Definition: homog2d_test.cpp:4056

◆ set() [3/3]

template<typename PLT , typename FPT >
template<typename FPT2 , typename T >
std::pair< HOMOG2D_INUMTYPE, HOMOG2D_INUMTYPE > h2d::base::PolylineBase< PLT, FPT >::set ( FPT2  rad,
ni 
)

Build RCP (Regular Convex Polygon), and return distance between consecutive points.

Build a Regular Convex Polygon of radius rad with n points, centered at (0,0)

Returns
segment distance, inscribed circle radius
Parameters
radRadius
niNb of points
6806 {
6807  static_assert(
6808  std::is_integral<T>::value,
6809  "2nd argument type must be integral type"
6810  );
6811  static_assert(
6812  std::is_same_v<PLT,typ::IsClosed>,
6813  "Cannot build a RCP as open polyline"
6814  );
6815 
6816  if( ni < 3 )
6817  HOMOG2D_THROW_ERROR_1( "unable, nb of points must be > 2" );
6818  if( rad <= 0 )
6819  HOMOG2D_THROW_ERROR_1( "unable, radius must be > 0" );
6820 
6821  size_t n(ni);
6822  std::vector<Point2d_<HOMOG2D_INUMTYPE>> v_pts(n);
6823  auto it = std::begin( v_pts );
6824  auto angle0 = (HOMOG2D_INUMTYPE)2. * M_PI / n;
6825 
6826  Point2d_<HOMOG2D_INUMTYPE> pt0( rad, 0. ); // initial point
6827  HOMOG2D_INUMTYPE radius = 0.;
6828 
6829  for( size_t i=0; i<n; i++ )
6830  {
6831  auto angle = angle0 * i;
6832  auto x = homog2d_cos( angle );
6833  auto y = homog2d_sin( angle );
6834 
6835  if( i == 1 ) // compute radius of inscribed circle
6836  {
6837  auto pt1 = Point2d_<HOMOG2D_INUMTYPE>( x * rad, y * rad );
6838  Segment_<HOMOG2D_INUMTYPE> seg( pt0, pt1 );
6839  Line2d_<HOMOG2D_INUMTYPE> li( seg.getCenter() ); // line passing through (0,0) and middle point of segment
6840  auto inters_pt = seg.intersects( li ) ; // intersection point
6841  assert( inters_pt() );
6842  radius = Point2d_<HOMOG2D_INUMTYPE>(0,0).distTo( inters_pt.get() );
6843  }
6844 
6845  *it = Point2d_<HOMOG2D_INUMTYPE>( x * rad, y * rad );
6846  it++;
6847  }
6848  *this = PolylineBase<PLT,FPT>( v_pts );
6849 
6850  return std::make_pair(
6851  getPoint(0).distTo( getPoint(1) ),
6852  radius
6853  );
6854 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6324
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
Segment seg
Definition: homog2d_test.cpp:4051
#define M_PI
Definition: homog2d.hpp:235
#define homog2d_cos
Definition: homog2d.hpp:71
Line2d li
Definition: homog2d_test.cpp:4053
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10997
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
FPT & radius(Circle_< FPT > &cir)
Returns reference on radius of circle (free function), non-const version.
Definition: homog2d.hpp:10920
#define homog2d_sin
Definition: homog2d.hpp:70

◆ setParallelogram()

template<typename PLT , typename FPT >
template<typename FPT1 , typename FPT2 , typename FPT3 >
void h2d::base::PolylineBase< PLT, FPT >::setParallelogram ( const Point2d_< FPT1 > &  pt1,
const Point2d_< FPT2 > &  pt2,
const Point2d_< FPT3 > &  pt3 
)

Build a parallelogram (4 points) from 3 points.

6774 {
6775  static_assert( std::is_same_v<PLT,typ::IsClosed>, "Invalid: cannot set a OPolyline as a parallelogram" );
6776 
6777  Point2d_<HOMOG2D_INUMTYPE> pt1(p1);
6778  Point2d_<HOMOG2D_INUMTYPE> pt2(p2);
6779  Point2d_<HOMOG2D_INUMTYPE> pt3(p3);
6780 
6781  std::vector<Point2d_<FPT>> vpts(4);
6782  vpts[0] = pt1;
6783  vpts[1] = pt2;
6784  vpts[2] = pt3;
6785 
6786  auto li_21 = pt1 * pt2;
6787  auto li_23 = pt3 * pt2;
6788  auto li_34 = li_21.getParallelLine( pt3 );
6789  auto li_14 = li_23.getParallelLine( pt1 );
6790  vpts[3] = li_34 * li_14;
6791  set( vpts );
6792 }
Here is the caller graph for this function:

◆ size()

template<typename PLT, typename FPT>
size_t h2d::base::PolylineBase< PLT, FPT >::size ( ) const
inlinevirtual

Returns the number of points.

Implements h2d::rtp::Root.

6215 { return _plinevec.size(); }
Here is the caller graph for this function:

◆ translate() [1/2]

template<typename PLT, typename FPT>
template<typename TX , typename TY >
void h2d::base::PolylineBase< PLT, FPT >::translate ( TX  dx,
TY  dy 
)
inline

Translate Polyline using dx, dy.

6416  {
6419  for( auto& pt: _plinevec )
6420  pt.translate( dx, dy );
6421  }
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
Point2d pt
Definition: homog2d_test.cpp:4052
Here is the caller graph for this function:

◆ translate() [2/2]

template<typename PLT, typename FPT>
template<typename T1 , typename T2 >
void h2d::base::PolylineBase< PLT, FPT >::translate ( const std::pair< T1, T2 > &  ppt)
inline

Translate Polyline, using a pair of numerical values.

6426  {
6427  translate( ppt.first, ppt.second );
6428  }
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6415

◆ type()

template<typename PLT, typename FPT>
Type h2d::base::PolylineBase< PLT, FPT >::type ( ) const
inlinevirtual

Implements h2d::rtp::Root.

6084  {
6085  if constexpr( std::is_same_v<PLT,typ::IsClosed> )
6086  return Type::CPolyline;
6087  else
6088  return Type::OPolyline;
6089  }

Friends And Related Function Documentation

◆ h2d::base::operator<<

template<typename PLT, typename FPT>
template<typename T1 , typename T2 >
std::ostream& h2d::base::operator<< ( std::ostream &  ,
const h2d::base::PolylineBase< T1, T2 > &   
)
friend

◆ h2d::Ellipse_

template<typename PLT, typename FPT>
template<typename T1 >
friend class h2d::Ellipse_
friend

◆ h2d::operator* [1/2]

template<typename PLT, typename FPT>
template<typename FPT1 , typename FPT2 >
CPolyline_<FPT1> h2d::operator* ( const h2d::Homogr_< FPT2 > &  ,
const h2d::FRect_< FPT1 > &   
)
friend

◆ h2d::operator* [2/2]

template<typename PLT, typename FPT>
template<typename FPT1 , typename FPT2 , typename PLT2 >
auto h2d::operator* ( const Homogr_< FPT2 > &  ,
const base::PolylineBase< PLT2, FPT1 > &   
) -> base::PolylineBase< PLT2, FPT1 >
friend

◆ PolylineBase

template<typename PLT, typename FPT>
template<typename T1 , typename T2 >
friend class PolylineBase
friend

The documentation for this class was generated from the following file: