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.

6102  {
6103  static_assert( std::is_same_v<PLT,typ::IsClosed>, "cannot build an OPolyline object from a FRect");
6104  for( const auto& pt: rect.get4Pts() )
6105  _plinevec.push_back( pt );
6106  }
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
6110  {
6111  const auto& ppts = seg.getPts();
6112  p_addPoint( ppts.first );
6113  p_addPoint( ppts.second );
6114  }
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.

6125  {
6126  set( vec );
6127  }

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

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

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

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

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

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

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

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

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

◆ convexHull()

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

Return convex hull (member function implementation)

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

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

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

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

◆ getBmPoint()

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

Return Bottom-most point of Polyline.

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

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

◆ getLmPoint()

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

Return Left-most point of Polyline.

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

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

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

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

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

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

6303  {
6304  return _plinevec;
6305  }

◆ getRmPoint()

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

Return Right-most point of Polyline.

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

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

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

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

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

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

◆ isClosed()

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

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

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

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

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

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

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

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

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

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

◆ 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 )
7266 {
7267  translate( -refpt.getX(), -refpt.getY() );
7268  this->rotate( rot );
7269  translate( refpt.getX(), refpt.getY() );
7270 }
void translate(TX dx, TY dy)
Translate Polyline using dx, dy.
Definition: homog2d.hpp:6411
void rotate(Rotate, const Point2d_< FPT2 > &)
Rotates the polyline by either 90°, 180°, 270° (-90°) at point refpt.
Definition: homog2d.hpp:7265
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>& )
7284 {
7285  switch( rot )
7286  {
7287  case Rotate::CCW:
7288  for( auto& pt: getPts() )
7289  pt.set( -pt.getY(), +pt.getX() );
7290  break;
7291  case Rotate::CW:
7292  for( auto& pt: getPts() )
7293  pt.set( +pt.getY(), -pt.getX() );
7294  break;
7295  case Rotate::Full:
7296  for( auto& pt: getPts() )
7297  pt.set( -pt.getX(), -pt.getY() );
7298  break;
7299  case Rotate::VMirror:
7300  for( auto& pt: getPts() )
7301  pt.set( -pt.getX(), pt.getY() );
7302  break;
7303  case Rotate::HMirror:
7304  for( auto& pt: getPts() )
7305  pt.set( pt.getX(), -pt.getY() );
7306  break;
7307 
7308  default: assert(0);
7309  }
7310 }
180° rotation
ClockWise rotation.
horizontal symmetry
Counter ClockWise rotation.
vertical symmetry
std::vector< Point2d_< FPT > > & getPts()
Returns the points (reference)
Definition: homog2d.hpp:6295
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
6462  {
6463 #ifndef HOMOG2D_NOCHECKS
6464  if( vec.size() == 1 )
6465  HOMOG2D_THROW_ERROR_1( "Invalid: number of points must be 0, 2 or more" );
6466  if( vec.size() > 1 )
6467  p_checkInputData( vec );
6468 #endif
6469  _attribs.setBad();
6470  _plIsNormalized=false;
6471  _plinevec.resize( vec.size() );
6472  auto it = std::begin( _plinevec );
6473  for( const auto& pt: vec ) // copying one by one will allow
6474  *it++ = pt; // type conversions (std::copy implies same FP type)
6475  }
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
void setBad()
Definition: homog2d.hpp:5881
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.

6487  {
6488  static_assert( std::is_same_v<PLT,typ::IsClosed>, "Invalid: cannot set a OPolyline from a FRect" );
6489 
6490  CPolyline_<FPT> tmp(rect);
6491  std::swap( *this, tmp );
6492  }
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
6802 {
6803  static_assert(
6804  std::is_integral<T>::value,
6805  "2nd argument type must be integral type"
6806  );
6807  static_assert(
6808  std::is_same_v<PLT,typ::IsClosed>,
6809  "Cannot build a RCP as open polyline"
6810  );
6811 
6812  if( ni < 3 )
6813  HOMOG2D_THROW_ERROR_1( "unable, nb of points must be > 2" );
6814  if( rad <= 0 )
6815  HOMOG2D_THROW_ERROR_1( "unable, radius must be > 0" );
6816 
6817  size_t n(ni);
6818  std::vector<Point2d_<HOMOG2D_INUMTYPE>> v_pts(n);
6819  auto it = std::begin( v_pts );
6820  auto angle0 = (HOMOG2D_INUMTYPE)2. * M_PI / n;
6821 
6822  Point2d_<HOMOG2D_INUMTYPE> pt0( rad, 0. ); // initial point
6823  HOMOG2D_INUMTYPE radius = 0.;
6824 
6825  for( size_t i=0; i<n; i++ )
6826  {
6827  auto angle = angle0 * i;
6828  auto x = homog2d_cos( angle );
6829  auto y = homog2d_sin( angle );
6830 
6831  if( i == 1 ) // compute radius of inscribed circle
6832  {
6833  auto pt1 = Point2d_<HOMOG2D_INUMTYPE>( x * rad, y * rad );
6834  Segment_<HOMOG2D_INUMTYPE> seg( pt0, pt1 );
6835  Line2d_<HOMOG2D_INUMTYPE> li( seg.getCenter() ); // line passing through (0,0) and middle point of segment
6836  auto inters_pt = seg.intersects( li ) ; // intersection point
6837  assert( inters_pt() );
6838  radius = Point2d_<HOMOG2D_INUMTYPE>(0,0).distTo( inters_pt.get() );
6839  }
6840 
6841  *it = Point2d_<HOMOG2D_INUMTYPE>( x * rad, y * rad );
6842  it++;
6843  }
6844  *this = PolylineBase<PLT,FPT>( v_pts );
6845 
6846  return std::make_pair(
6847  getPoint(0).distTo( getPoint(1) ),
6848  radius
6849  );
6850 }
Point2d_< FPT > getPoint(size_t idx) const
Returns one point of the polyline.
Definition: homog2d.hpp:6320
#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:10993
#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:10916
#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.

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

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

6412  {
6415  for( auto& pt: _plinevec )
6416  pt.translate( dx, dy );
6417  }
#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.

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

◆ type()

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

Implements h2d::rtp::Root.

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

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: