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.

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

◆ PolylineBase() [3/8]

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

◆ 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.

6126  {
6127  set( vec );
6128  }

◆ 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).

6133  {
6134  set( rad, n );
6135  }

◆ 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.

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

◆ 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.

6150  {
6151  set( other._plinevec );
6152  }

◆ 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
6176  {
6177  const auto& outer = bgpol.outer();
6178  bool isClosed = false;
6179  auto ptf = outer.front();
6180  auto ptb = outer.back();
6181  Point2d_<HOMOG2D_INUMTYPE> pt_front( boost::geometry::get<0>(ptf), boost::geometry::get<1>(ptf) );
6182  Point2d_<HOMOG2D_INUMTYPE> pt_back( boost::geometry::get<0>(ptb), boost::geometry::get<1>(ptb) );
6183 /*
6184 this should work !!! (but doesn't...)
6185  Point2d_<HOMOG2D_INUMTYPE> pt_front( outer.front() );
6186  Point2d_<HOMOG2D_INUMTYPE> pt_back( outer.back() );
6187 */
6188  if( pt_front == pt_back ) // means it's closed
6189  isClosed = true;
6190 
6191  if( isClosed && std::is_same_v<PLT,typ::IsOpen> ) // cannot build an open polyline from a closed one
6192  HOMOG2D_THROW_ERROR_1( "unable to convert a closed boost::polygon into an OPolyline" );
6193 
6194  _plinevec.reserve( outer.size() - isClosed );
6195  for( auto it=outer.begin(); it!=outer.end()-isClosed; it++ )
6196  {
6197  const auto& bgpt = *it;
6198  _plinevec.emplace_back(
6199  Point2d_<FPT>( boost::geometry::get<0>(bgpt), boost::geometry::get<1>(bgpt) )
6200  );
6201  }
6202  }
constexpr bool isClosed() const
Definition: homog2d.hpp:6214
#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.

7483 {
7484  if( !isSimple() ) // implies that is both closed and has no intersections
7485  return 0.;
7486 
7487  if( _attribs._area.isBad() )
7488  _attribs._area.set( homog2d_abs( p_ComputeSignedArea() ) );
7489  return _attribs._area.value();
7490 }
void set(T v)
Definition: homog2d.hpp:5862
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7382
#define homog2d_abs
Definition: homog2d.hpp:69
bool isBad() const
Definition: homog2d.hpp:5869
priv::ValueFlag< HOMOG2D_INUMTYPE > _area
Definition: homog2d.hpp:5878
T value() const
Definition: homog2d.hpp:5867
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!
7520 {
7521  if( !isSimple() )
7522  HOMOG2D_THROW_ERROR_1( "unable, Polyline object is not simple" );
7523 
7524  if( _attribs._centroid.isBad() )
7525  {
7526  HOMOG2D_INUMTYPE cx = 0.;
7527  HOMOG2D_INUMTYPE cy = 0.;
7528  for( size_t i=0; i<size(); i++ )
7529  {
7530  auto j = (i == size()-1 ? 0 : i+1);
7531  const auto& pt1 = _plinevec[i];
7532  const auto& pt2 = _plinevec[j];
7533  auto x1 = pt1.getX();
7534  auto x2 = pt2.getX();
7535  auto y1 = pt1.getY();
7536  auto y2 = pt2.getY();
7537 
7538  auto prod = x1*y2 - x2*y1;
7539  cx += (x1+x2) * prod;
7540  cy += (y1+y2) * prod;
7541  }
7542  auto signedArea = p_ComputeSignedArea();
7543  cx /= (6. * signedArea);
7544  cy /= (6. * signedArea);
7545 
7546  auto c = Point2d_<HOMOG2D_INUMTYPE>( cx, cy );
7547  _attribs._centroid.set( c );
7548  }
7549  return _attribs._centroid.value();
7550 }
#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:7382
priv::ValueFlag< Point2d_< HOMOG2D_INUMTYPE > > _centroid
Definition: homog2d.hpp:5880
#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:6212
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).

6377  {
6378  _plinevec.clear();
6379  _plIsNormalized=false;
6380  _attribs.setBad();
6381  }
void setBad()
Definition: homog2d.hpp:5882

◆ convexHull()

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

Return convex hull (member function implementation)

11625 {
11626  return h2d::convexHull( *this );
11627 }
CPolyline_< FPT > convexHull(const base::PolylineBase< CT, FPT > &input)
Compute Convex Hull of a Polyline (free function)
Definition: homog2d.hpp:11537
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.

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

11951 {
11952  if( size() < 2 ) // nothing to draw
11953  return;
11954 
11955  for( size_t i=0; i<nbSegs(); i++ )
11956  getSegment(i).draw( im, dp );
11957 
11958  if( dp._dpValues._showPoints )
11959  {
11960  auto newPointStyle = dp._dpValues.nextPointStyle();
11961  getPoint(0).draw( im, dp.setColor(10,10,10).setPointStyle( newPointStyle ) );
11962  }
11963 
11964  if( dp._dpValues._showIndex )
11965  for( size_t i=0; i<size(); i++ )
11966  {
11967  auto pt = getPoint(i);
11968  cv::putText(
11969  im.getReal(),
11970  std::to_string(i),
11971  pt.getCvPti(),
11972  0,
11973  0.6,
11974  cv::Scalar( 20,20,20 ),
11975  2
11976  );
11977  }
11978 
11979  if( dp._dpValues._showAngles )
11980  {
11981  auto osegs = getOSegs();
11982 // std::cout << "osegs size=" << osegs.size() << "\n";
11983 
11984  const auto& pts = getPts();
11985  for( size_t i=0; i<osegs.size()-1; i++ )
11986  {
11987  auto seg1 = osegs[i];
11988  auto seg2 = osegs[i+1];
11989  auto angle = getAngle( seg1, seg2 );
11990 // std::cout << "angle " << i << "=" << angle*180/3.1415 << "\n";
11991  drawText( im, std::to_string(angle * 180./M_PI), pts[i+1] );
11992  }
11993  if( isClosed() )
11994  {
11995  auto seg1 = osegs.back();
11996  auto seg2 = osegs.front();
11997  auto angle = getAngle( seg1, seg2 );
11998 // std::cout << "final angle " << "=" << angle*180/3.1415 << "\n";
11999  drawText( im, std::to_string(angle * 180./M_PI), pts[0] );
12000  }
12001  }
12002 }
size_t nbSegs() const
Returns the number of segments. If "closed",.
Definition: homog2d.hpp:6246
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6321
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:11261
HOMOG2D_INUMTYPE getAngle(const T1 &, const T2 &)
Free function, returns angle between two segments/lines.
Definition: homog2d.hpp:9205
#define M_PI
Definition: homog2d.hpp:235
Segment_< FPT > getSegment(size_t idx) const
Returns one segment of the polyline.
Definition: homog2d.hpp:6363
HOMOG2D_INUMTYPE angle(const Ellipse_< FPT > &ell)
Return angle of ellipse (free function)
Definition: homog2d.hpp:10994
std::vector< OSegment_< FPT > > getOSegs() const
Returns (as a copy) the oriented segments of the polyline.
Definition: homog2d.hpp:6309
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
constexpr bool isClosed() const
Definition: homog2d.hpp:6214
img::Image< img::SvgImage > im(300, 400)
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212
Point2d pt
Definition: homog2d_test.cpp:4034

◆ getBB()

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

Returns Bounding Box of Polyline.

6228  {
6229  HOMOG2D_START;
6230 #ifndef HOMOG2D_NOCHECKS
6231  if( size() < 2 )
6232  HOMOG2D_THROW_ERROR_1( "cannot compute bounding box of empty Polyline" );
6233 #endif
6234  auto ppts = priv::getBB_Points( getPts() );
6235 #ifndef HOMOG2D_NOCHECKS
6236  if( shareCommonCoord( ppts.first, ppts.second ) )
6237  HOMOG2D_THROW_ERROR_1( "unable, points share common coordinate" );
6238 #endif
6239  return FRect_<HOMOG2D_INUMTYPE>( ppts );
6240  }
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:5904
#define HOMOG2D_START
Definition: homog2d.hpp:106
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
#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:6212
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
6651  {
6652  return h2d::getBisectorLines( *this );
6653  }
std::vector< Line2d_< HOMOG2D_INUMTYPE > > getBisectorLines(const base::PolylineBase< PLT, FPT > &)
Returns bisector lines of a Polyline.
Definition: homog2d.hpp:9983

◆ getBmPoint()

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

Return Bottom-most point of Polyline.

7123 {
7124  return h2d::getBmPoint( *this );
7125 }
auto getBmPoint(const T &t)
Return Bottom-most point of container holding points.
Definition: homog2d.hpp:6916
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.

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

◆ getLmPoint()

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

Return Left-most point of Polyline.

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

◆ 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.

6355  {
6356  return impl_getSegment( idx, OSegment_<FPT>() );
6357  }
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.

6310  {
6311  return priv::p_getSegs( *this, OSegment_<FPT>() );
6312  }
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:5997
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.

6322  {
6323 #ifndef HOMOG2D_NOCHECKS
6324  if( idx >= size() )
6325  HOMOG2D_THROW_ERROR_1( "requesting point " << idx
6326  << ", only has " << size()
6327  );
6328 #endif
6329  return _plinevec[idx];
6330  }
#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:6212
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)

6297  {
6298  _attribs.setBad(); // because we send the non-const reference
6299  _plIsNormalized=false;
6300  return _plinevec;
6301  }
void setBad()
Definition: homog2d.hpp:5882
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)

6304  {
6305  return _plinevec;
6306  }

◆ getRmPoint()

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

Return Right-most point of Polyline.

7147 {
7148  return h2d::getRmPoint( *this );
7149 }
auto getRmPoint(const T &t)
Return Right-most point of container holding points.
Definition: homog2d.hpp:7029
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

6364  {
6365  return impl_getSegment( idx, Segment_<FPT>() );
6366  }

◆ 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.

6316  {
6317  return priv::p_getSegs( *this, Segment_<FPT>() );
6318  }
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:5997
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.

7131 {
7132  return h2d::getTmPoint( *this );
7133 }
auto getTmPoint(const T &t)
Return Top-most point of container.
Definition: homog2d.hpp:6941
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.

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

◆ isClosed()

template<typename PLT, typename FPT>
constexpr bool h2d::base::PolylineBase< PLT, FPT >::isClosed ( ) const
inline
6215  {
6216  if constexpr( std::is_same_v<PLT,typ::IsClosed> )
6217  return true;
6218  else
6219  return false;
6220  }
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
7432 {
7433  if( !isSimple() )
7434  return false;
7435 
7436  int8_t sign = 0;
7437  const auto& vpts = getPts();
7438  if( vpts.size() == 3 ) // 3 pts => always convex
7439  return true;
7440 
7441  for( size_t i=0; i<vpts.size(); i++ )
7442  {
7443  const auto& pt0 = vpts[ i==0?vpts.size()-1:i-1 ];
7444  const auto& pt1 = vpts[ i ];
7445  const auto& pt2 = vpts[ i==vpts.size()-1?0:i+1 ];
7446  auto dx1 = pt1.getX() - pt0.getX();
7447  auto dy1 = pt1.getY() - pt0.getY();
7448 
7449  auto dx2 = pt2.getX() - pt1.getX();
7450  auto dy2 = pt2.getY() - pt1.getY();
7451 
7452  auto crossproduct = dx1*dy2 - dy1*dx2;
7453  if( sign == 0 ) // initial sign value
7454  sign = (crossproduct>0 ? +1 : -1);
7455  else
7456  if (sign != (crossproduct>0 ? +1 : -1) )
7457  return false;
7458  }
7459  return true;
7460 }
bool isSimple() const
Returns true if object is a polygon (closed, and no segment crossing)
Definition: homog2d.hpp:7382
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
int sign(T val)
Get sign of value.
Definition: homog2d.hpp:3564
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

6598  {
6599  HOMOG2D_START;
6600  if( size() == 0 )
6601  return false;
6602  for( const auto& pt: getPts() )
6603  if( !pt.isInside( prim ) )
6604  return false;
6605  return true;
6606  }
#define HOMOG2D_START
Definition: homog2d.hpp:106
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212
Point2d pt
Definition: homog2d_test.cpp:4034
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

6620  {
6621  HOMOG2D_START;
6622  if( size() == 0 )
6623  return false;
6624  for( const auto& pt: getPts() )
6625  if( !pt.isInside( cpol ) )
6626  return false;
6627  if( intersects(cpol)() )
6628  return false;
6629  return true;
6630  }
#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:6569
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
CPolyline cpol
Definition: homog2d_test.cpp:4030
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212
Point2d pt
Definition: homog2d_test.cpp:4034

◆ 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)

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

7467 {
7468  if( _attribs._length.isBad() )
7469  {
7470  HOMOG2D_INUMTYPE sum = 0.;
7471  for( const auto& seg: getSegs() )
7472  sum += static_cast<HOMOG2D_INUMTYPE>( seg.length() );
7473  _attribs._length.set( sum );
7474  }
7475  return _attribs._length.value();
7476 }
std::vector< Segment_< FPT > > getSegs() const
Returns (as a copy) the segments of the polyline.
Definition: homog2d.hpp:6315
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
void set(T v)
Definition: homog2d.hpp:5862
Segment seg
Definition: homog2d_test.cpp:4033
bool isBad() const
Definition: homog2d.hpp:5869
priv::ValueFlag< HOMOG2D_INUMTYPE > _length
Definition: homog2d.hpp:5877
T value() const
Definition: homog2d.hpp:5867
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:
6404  {
6405  if( size()<3 )
6406  return;
6407  impl_minimizePL( detail::PlHelper<PLT>() );
6408  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212

◆ 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.

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

◆ 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!
6442  {
6443  if( size() == 0 )
6444  HOMOG2D_THROW_ERROR_1( "Invalid call, Polyline is empty" );
6445  auto dx = new_org.getX() - getPoint(0).getX();
6446  auto dy = new_org.getY() - getPoint(0).getY();
6447  for( auto& pt: _plinevec )
6448  pt.translate( dx, dy );
6449  }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6321
#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:6212
Point2d pt
Definition: homog2d_test.cpp:4034

◆ 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

6247  {
6248  if( size() < 2 )
6249  return 0;
6250  if constexpr( std::is_same_v<PLT,typ::IsClosed> )
6251  return size();
6252  else
6253  return size() - 1;
6254  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212
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
6556  {
6557  return !( *this == other );
6558  }

◆ 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
6535  {
6536  if constexpr( std::is_same_v<PLT,PLT2> )
6537  {
6538  if( size() != other.size() ) // for quick exit
6539  return false;
6540 
6541  p_normalizePoly();
6542  other.p_normalizePoly();
6543 
6544  auto it = other._plinevec.begin();
6545  for( const auto& elem: _plinevec )
6546  if( *it++ != elem )
6547  return false;
6548  return true;
6549  }
6550  else
6551  return false;
6552  }
size_t size() const
Returns the number of points.
Definition: homog2d.hpp:6212

◆ 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 )
7267 {
7268  translate( -refpt.getX(), -refpt.getY() );
7269  this->rotate( rot );
7270  translate( refpt.getX(), refpt.getY() );
7271 }
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6412
void rotate(Rotate, const Point2d_< FPT2 > &)
Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt.
Definition: homog2d.hpp:7266
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>& )
7285 {
7286  switch( rot )
7287  {
7288  case Rotate::CCW:
7289  for( auto& pt: getPts() )
7290  pt.set( -pt.getY(), +pt.getX() );
7291  break;
7292  case Rotate::CW:
7293  for( auto& pt: getPts() )
7294  pt.set( +pt.getY(), -pt.getX() );
7295  break;
7296  case Rotate::Full:
7297  for( auto& pt: getPts() )
7298  pt.set( -pt.getX(), -pt.getY() );
7299  break;
7300  case Rotate::VMirror:
7301  for( auto& pt: getPts() )
7302  pt.set( -pt.getX(), pt.getY() );
7303  break;
7304  case Rotate::HMirror:
7305  for( auto& pt: getPts() )
7306  pt.set( pt.getX(), -pt.getY() );
7307  break;
7308 
7309  default: assert(0);
7310  }
7311 }
180° rotation
ClockWise rotation.
horizontal symmetry
Counter ClockWise rotation.
vertical symmetry
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6296
Point2d pt
Definition: homog2d_test.cpp:4034

◆ 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
6463  {
6464 #ifndef HOMOG2D_NOCHECKS
6465  if( vec.size() == 1 )
6466  HOMOG2D_THROW_ERROR_1( "Invalid: number of points must be 0, 2 or more" );
6467  if( vec.size() > 1 )
6468  p_checkInputData( vec );
6469 #endif
6470  _attribs.setBad();
6471  _plIsNormalized=false;
6472  _plinevec.resize( vec.size() );
6473  auto it = std::begin( _plinevec );
6474  for( const auto& pt: vec ) // copying one by one will allow
6475  *it++ = pt; // type conversions (std::copy implies same FP type)
6476  }
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
void setBad()
Definition: homog2d.hpp:5882
Point2d pt
Definition: homog2d_test.cpp:4034
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.

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

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

6771 {
6772  static_assert( std::is_same_v<PLT,typ::IsClosed>, "Invalid: cannot set a OPolyline as a parallelogram" );
6773 
6774  Point2d_<HOMOG2D_INUMTYPE> pt1(p1);
6775  Point2d_<HOMOG2D_INUMTYPE> pt2(p2);
6776  Point2d_<HOMOG2D_INUMTYPE> pt3(p3);
6777 
6778  std::vector<Point2d_<FPT>> vpts(4);
6779  vpts[0] = pt1;
6780  vpts[1] = pt2;
6781  vpts[2] = pt3;
6782 
6783  auto li_21 = pt1 * pt2;
6784  auto li_23 = pt3 * pt2;
6785  auto li_34 = li_21.getParallelLine( pt3 );
6786  auto li_14 = li_23.getParallelLine( pt1 );
6787  vpts[3] = li_34 * li_14;
6788  set( vpts );
6789 }
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.

6212 { 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.

6413  {
6416  for( auto& pt: _plinevec )
6417  pt.translate( dx, dy );
6418  }
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
Point2d pt
Definition: homog2d_test.cpp:4034
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.

6423  {
6424  translate( ppt.first, ppt.second );
6425  }
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6412

◆ type()

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

Implements h2d::rtp::Root.

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

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: