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

A circle. More...

#include <homog2d.hpp>

Inheritance diagram for h2d::Circle_< FPT >:
Inheritance graph
[legend]
Collaboration diagram for h2d::Circle_< FPT >:
Collaboration graph
[legend]

Public Types

using FType = FPT
 
using SType = typ::T_Circle
 

Public Member Functions

void draw (img::Image< cv::Mat > &, img::DrawParams=img::DrawParams()) const
 Draw Circle (Opencv implementation) More...
 
void draw (img::Image< img::SvgImage > &, img::DrawParams=img::DrawParams()) const
 Draw Circle (SVG implementation) More...
 
Type type () const
 
Constructors
 Circle_ ()
 Default constructor, unit-radius circle at (0,0) More...
 
template<typename T , typename std::enable_if< std::is_arithmetic< T >::value, T >::type * = nullptr>
 Circle_ (T rad)
 1-arg constructor 1, given radius circle at (0,0) More...
 
template<typename FPT2 >
 Circle_ (Point2d_< FPT2 > center)
 1-arg constructor 2, given center point, radius = 1.0 More...
 
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * = nullptr>
 Circle_ (const T &pts)
 1-arg constructor 3, build circle from a set of 2, 3, or more points (Minimum Enclosing Circle, aka MEC) More...
 
template<typename T1 , typename T2 >
 Circle_ (const Point2d_< T1 > &center, T2 rad=1.0)
 2-arg constructor 1: point and radius More...
 
template<typename T1 , typename T2 >
 Circle_ (const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2)
 2-arg constructor 2: circle from 2 points (may be of different types) More...
 
template<typename T1 , typename T2 , typename std::enable_if<(std::is_arithmetic< T1 >::value &&!std::is_same< T1, bool >::value), T1 >::type * = nullptr>
 Circle_ (T1 x, T1 y, T2 rad)
 3-arg constructor 1: build circle from 3 floating-point values: x, y, radius More...
 
template<typename T1 , typename T2 , typename T3 >
 Circle_ (const Point2d_< T1 > &pt1, const Point2d_< T2 > &pt2, const Point2d_< T3 > &pt3)
 3-arg constructor 2: builds a circle from 3 points More...
 
template<typename FPT2 >
 Circle_ (const Circle_< FPT2 > &other)
 Copy-Constructor. More...
 
Attributes access
FPT & radius ()
 
const FPT & radius () const
 
Point2d_< FPT > & center ()
 
const Point2d_< FPT > & center () const
 
const Point2d_< FPT > & getCenter () const
 
constexpr size_t size () const
 
HOMOG2D_INUMTYPE area () const
 Area of circle. More...
 
HOMOG2D_INUMTYPE length () const
 Perimeter of circle. More...
 
auto getBB () const
 Returns Bounding Box of circle. More...
 
Enclosing functions
template<typename FPT2 >
bool isInside (const Circle_< FPT2 > &other) const
 Returns true if circle is inside other circle. More...
 
template<typename FPT2 >
bool isInside (const Point2d_< FPT2 > &p1, const Point2d_< FPT2 > &p2) const
 Returns true if circle is inside rectangle defined by p1 and p2. More...
 
template<typename FPT2 >
bool isInside (const FRect_< FPT2 > &rect) const
 Returns true if circle is inside flat rectangle rect. More...
 
template<typename FPT2 , typename PTYPE >
bool isInside (const base::PolylineBase< PTYPE, FPT2 > &poly) const
 Returns true if circle is inside polyline. More...
 
Intersection functions
template<typename FPT2 >
detail::Intersect< detail::Inters_2, FPT > intersects (const Line2d_< FPT2 > &li) const
 Circle/Line intersection. More...
 
template<typename FPT2 >
detail::IntersectM< FPT > intersects (const Segment_< FPT2 > &seg) const
 Circle/Segment intersection. More...
 
template<typename FPT2 >
detail::IntersectM< FPT > intersects (const Circle_< FPT2 > &) const
 Circle/Circle intersection. More...
 
template<typename FPT2 >
detail::IntersectM< FPT > intersects (const FRect_< FPT2 > &rect) const
 Circle/FRect intersection. More...
 
template<typename PLT , typename FPT2 >
detail::IntersectM< FPT > intersects (const base::PolylineBase< PLT, FPT2 > &pl) const
 Circle/Polyline intersection. More...
 
Operators
template<typename FPT2 >
bool operator== (const Circle_< FPT2 > &other) const
 
template<typename FPT2 >
bool operator!= (const Circle_< 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 T >
class Circle_
 
template<typename T >
std::ostream & operator<< (std::ostream &f, const Circle_< T > &r)
 

Edit values

template<typename PT >
void set (const Point2d_< PT > &center)
 Set circle center point, radius unchanged. More...
 
template<typename T , typename std::enable_if<(std::is_arithmetic< T >::value &&!std::is_same< T, bool >::value), T >::type * = nullptr>
void set (T rad)
 Set circle radius, center point unchanged. More...
 
template<typename FPT2 , typename FPT3 >
void set (const Point2d_< FPT2 > &center, FPT3 rad)
 Set circle from center point and radius. More...
 
template<typename FPT2 , typename std::enable_if< std::is_arithmetic< FPT2 >::value, FPT2 >::type * = nullptr>
void set (FPT2 x, FPT2 y, FPT2 rad)
 Set circle from 3 values (x0,y0,radius) More...
 
template<typename T1 , typename T2 >
void set (const Point2d_< T1 > &, const Point2d_< T2 > &)
 Set circle from 2 points. More...
 
template<typename T1 , typename T2 , typename T3 >
void set (const Point2d_< T1 > &, const Point2d_< T2 > &, const Point2d_< T3 > &)
 Set circle from 3 points. More...
 
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * = nullptr>
void set (const T &)
 Compute circle from a set of points (Minimum Enclosing Circle, aka MEC) using the Welzl algorithm. More...
 
template<typename TX , typename TY >
void translate (TX dx, TY dy)
 Translate Circle. More...
 
template<typename T1 , typename T2 >
void translate (const std::pair< T1, T2 > &pa)
 Translate Circle. More...
 
template<typename TX , typename TY >
void moveTo (TX x, TY y)
 Move Circle to other location. More...
 
template<typename T1 >
void moveTo (const Point2d_< T1 > &pt)
 Move Circle to other location, geiven by pt. More...
 

Detailed Description

template<typename FPT>
class h2d::Circle_< FPT >

A circle.

Member Typedef Documentation

◆ FType

template<typename FPT>
using h2d::Circle_< FPT >::FType = FPT

◆ SType

template<typename FPT>
using h2d::Circle_< FPT >::SType = typ::T_Circle

Constructor & Destructor Documentation

◆ Circle_() [1/9]

template<typename FPT>
h2d::Circle_< FPT >::Circle_ ( )
inline

Default constructor, unit-radius circle at (0,0)

3201  : _radius(1.)
3202  {}
Here is the call graph for this function:

◆ Circle_() [2/9]

template<typename FPT>
template<typename T , typename std::enable_if< std::is_arithmetic< T >::value, T >::type * = nullptr>
h2d::Circle_< FPT >::Circle_ ( rad)
inlineexplicit

1-arg constructor 1, given radius circle at (0,0)

3213  : Circle_( Point2d_<FPT>(), rad )
3214  {}
Circle_()
Default constructor, unit-radius circle at (0,0)
Definition: homog2d.hpp:3201

◆ Circle_() [3/9]

template<typename FPT>
template<typename FPT2 >
h2d::Circle_< FPT >::Circle_ ( Point2d_< FPT2 >  center)
inlineexplicit

1-arg constructor 2, given center point, radius = 1.0

3219  : Circle_( center, 1. )
3220  {}
Circle_()
Default constructor, unit-radius circle at (0,0)
Definition: homog2d.hpp:3201
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294

◆ Circle_() [4/9]

template<typename FPT>
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * = nullptr>
h2d::Circle_< FPT >::Circle_ ( const T &  pts)
inlineexplicit

1-arg constructor 3, build circle from a set of 2, 3, or more points (Minimum Enclosing Circle, aka MEC)

3232  {
3233  set( pts );
3234  }

◆ Circle_() [5/9]

template<typename FPT>
template<typename T1 , typename T2 >
h2d::Circle_< FPT >::Circle_ ( const Point2d_< T1 > &  center,
T2  rad = 1.0 
)
inline

2-arg constructor 1: point and radius

3239  : _radius(rad), _center(center)
3240  {
3241 #ifndef HOMOG2D_NOCHECKS
3243  HOMOG2D_THROW_ERROR_1( "radius value too small: " << std::scientific << homog2d_abs(rad) );
3244  if( rad < 0. )
3245  HOMOG2D_THROW_ERROR_1( "radius must not be <0" );
3246 #endif
3247  }
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1229
#define homog2d_abs
Definition: homog2d.hpp:69
static bool & doNotCheckRadius()
This one is used for the Welzl minimum enclosing circle.
Definition: homog2d.hpp:1258
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294
Here is the call graph for this function:

◆ Circle_() [6/9]

template<typename FPT>
template<typename T1 , typename T2 >
h2d::Circle_< FPT >::Circle_ ( const Point2d_< T1 > &  pt1,
const Point2d_< T2 > &  pt2 
)
inline

2-arg constructor 2: circle from 2 points (may be of different types)

3252  {
3253  set( pt1, pt2 );
3254  }
Here is the call graph for this function:

◆ Circle_() [7/9]

template<typename FPT>
template<typename T1 , typename T2 , typename std::enable_if<(std::is_arithmetic< T1 >::value &&!std::is_same< T1, bool >::value), T1 >::type * = nullptr>
h2d::Circle_< FPT >::Circle_ ( T1  x,
T1  y,
T2  rad 
)
inline

3-arg constructor 1: build circle from 3 floating-point values: x, y, radius

We need Sfinae because there is another 3-args constructor (circle from 3 points)

3269  : Circle_( Point2d_<FPT>(x,y), rad )
3270  {
3271 // HOMOG2D_CHECK_IS_NUMBER(T1); // not needed, done by sfinae above
3273  }
Circle_()
Default constructor, unit-radius circle at (0,0)
Definition: homog2d.hpp:3201
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144

◆ Circle_() [8/9]

template<typename FPT>
template<typename T1 , typename T2 , typename T3 >
h2d::Circle_< FPT >::Circle_ ( const Point2d_< T1 > &  pt1,
const Point2d_< T2 > &  pt2,
const Point2d_< T3 > &  pt3 
)
inline

3-arg constructor 2: builds a circle from 3 points

3278  {
3279  set( pt1, pt2, pt3 );
3280  }

◆ Circle_() [9/9]

template<typename FPT>
template<typename FPT2 >
h2d::Circle_< FPT >::Circle_ ( const Circle_< FPT2 > &  other)
inline

Copy-Constructor.

3285  : _radius(other._radius), _center(other._center)
3286  {}

Member Function Documentation

◆ area()

template<typename FPT>
HOMOG2D_INUMTYPE h2d::Circle_< FPT >::area ( ) const
inlinevirtual

Area of circle.

Implements h2d::rtp::Root.

3305  {
3306  return static_cast<HOMOG2D_INUMTYPE>(_radius) * _radius * M_PI;
3307  }
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
#define M_PI
Definition: homog2d.hpp:235
Here is the caller graph for this function:

◆ center() [1/2]

template<typename FPT>
Point2d_<FPT>& h2d::Circle_< FPT >::center ( )
inline
3294 { return _center; }
Here is the caller graph for this function:

◆ center() [2/2]

template<typename FPT>
const Point2d_<FPT>& h2d::Circle_< FPT >::center ( ) const
inline
3295 { return _center; }

◆ draw() [1/2]

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

Draw Circle (Opencv implementation)

Implements h2d::rtp::Root.

11909 {
11910  cv::circle(
11911  im.getReal(),
11912  _center.getCvPti(),
11913  static_cast<int>(_radius),
11914  dp.cvColor(),
11915  dp._dpValues._lineThickness,
11916  dp._dpValues._lineType==1?cv::LINE_AA:cv::LINE_8
11917  );
11918  if( dp._dpValues._showPoints )
11919  // WARNING: can't use the "Dot" style here, because it call this function, so infinite recursion
11920  _center.draw( im, dp.setPointStyle( img::PtStyle::Plus) );
11921 }
img::Image< img::SvgImage > im(300, 400)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ draw() [2/2]

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

Draw Circle (SVG implementation)

Implements h2d::rtp::Root.

12073 {
12074  im.getReal()._svgString
12075  << "<circle cx=\"" << center().getX()
12076  << "\" cy=\"" << center().getY()
12077  << "\" r=\"" << radius()
12078  << "\" stroke=\""
12079  << dp.getSvgRgbColor()
12080  << "\" stroke-width=\"" << dp._dpValues._lineThickness << "\" ";
12081  if( !dp.holdsFill() )
12082  im.getReal()._svgString << "fill=\"none\" ";
12083  im.getReal()._svgString << dp.getAttrString()
12084  << "/>\n";
12085 }
img::Image< img::SvgImage > im(300, 400)
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294
FPT & radius()
Definition: homog2d.hpp:3291
Here is the call graph for this function:

◆ getBB()

template<typename FPT>
auto h2d::Circle_< FPT >::getBB ( ) const
inline

Returns Bounding Box of circle.

3317  {
3318  return FRect_<HOMOG2D_INUMTYPE>(
3319  static_cast<HOMOG2D_INUMTYPE>( _center.getX() ) - _radius,
3320  static_cast<HOMOG2D_INUMTYPE>( _center.getY() ) - _radius,
3321  static_cast<HOMOG2D_INUMTYPE>( _center.getX() ) + _radius,
3322  static_cast<HOMOG2D_INUMTYPE>( _center.getY() ) + _radius
3323  );
3324  }
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
Here is the call graph for this function:
Here is the caller graph for this function:

◆ getCenter()

template<typename FPT>
const Point2d_<FPT>& h2d::Circle_< FPT >::getCenter ( ) const
inline
3296 { return _center; }

◆ intersects() [1/5]

template<typename FPT>
template<typename FPT2 >
detail::Intersect<detail::Inters_2,FPT> h2d::Circle_< FPT >::intersects ( const Line2d_< FPT2 > &  li) const
inline

Circle/Line intersection.

3470  {
3471  return li.intersects( *this );
3472  }
Line2d li
Definition: homog2d_test.cpp:4035
Here is the call graph for this function:
Here is the caller graph for this function:

◆ intersects() [2/5]

template<typename FPT>
template<typename FPT2 >
detail::IntersectM<FPT> h2d::Circle_< FPT >::intersects ( const Segment_< FPT2 > &  seg) const
inline

Circle/Segment intersection.

3478  {
3479  return seg.intersects( *this );
3480  }
Segment seg
Definition: homog2d_test.cpp:4033
Here is the call graph for this function:

◆ intersects() [3/5]

template<typename FPT >
template<typename FPT2 >
detail::IntersectM< FPT > h2d::Circle_< FPT >::intersects ( const Circle_< FPT2 > &  other) const

Circle/Circle intersection.

Ref:

Can return 0, 1, or 2 intersection points

Todo:
20230219: in some situation, the difference below (x2 - x1) can be numericaly instable. Check if things would get improved by multiplying first (by a/d and h/d), before proceeding the difference.
5803 {
5804  if( *this == other )
5805  return detail::IntersectM<FPT>();
5806 
5807  HOMOG2D_INUMTYPE r1 = _radius;
5808  HOMOG2D_INUMTYPE r2 = other._radius;
5809  Point2d_<HOMOG2D_INUMTYPE> pt1 = _center;
5810  Point2d_<HOMOG2D_INUMTYPE> pt2 = other._center;
5811 
5812  HOMOG2D_INUMTYPE x1 = pt1.getX();
5813  HOMOG2D_INUMTYPE y1 = pt1.getY();
5814  HOMOG2D_INUMTYPE x2 = pt2.getX();
5815  HOMOG2D_INUMTYPE y2 = pt2.getY();
5816  HOMOG2D_INUMTYPE d_squared = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
5817 
5818  if( d_squared > r1*r1 + r2*r2 + (HOMOG2D_INUMTYPE)2.*r1*r2 ) // no intersection
5819  return detail::IntersectM<FPT>();
5820 
5821  if( d_squared < ( r1*r1 + r2*r2 - (HOMOG2D_INUMTYPE)2.*r1*r2 ) ) // no intersection: one circle inside the other
5822  return detail::IntersectM<FPT>();
5823 
5824  auto d = homog2d_sqrt( d_squared );
5825  auto a = (r1*r1 - r2*r2 + d_squared) / (HOMOG2D_INUMTYPE)2. / d;
5826  auto h = homog2d_sqrt( r1*r1 - a*a );
5827 
5828  Point2d_<FPT> P0(
5829  ( x2 - x1 ) * a / d + x1,
5830  ( y2 - y1 ) * a / d + y1
5831  );
5832 
5833  Point2d_<FPT> pt3(
5834  P0.getX() + ( y1 - y2 ) * h / d,
5835  P0.getY() - ( x1 - x2 ) * h / d
5836  );
5837  Point2d_<FPT> pt4(
5838  P0.getX() - ( y1 - y2 ) * h / d,
5839  P0.getY() + ( x1 - x2 ) * h / d
5840  );
5841 
5842  detail::IntersectM<FPT> out;
5843  out.add( pt3 );
5844  if( pt3 != pt4 )
5845  out.add( pt4 );
5846  return out;
5847 }
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
#define homog2d_sqrt
Definition: homog2d.hpp:75
Here is the call graph for this function:

◆ intersects() [4/5]

template<typename FPT>
template<typename FPT2 >
detail::IntersectM<FPT> h2d::Circle_< FPT >::intersects ( const FRect_< FPT2 > &  rect) const
inline

Circle/FRect intersection.

3490  {
3491  return rect.intersects( * this );
3492  }
FRect rect
Definition: homog2d_test.cpp:4038
Here is the call graph for this function:

◆ intersects() [5/5]

template<typename FPT>
template<typename PLT , typename FPT2 >
detail::IntersectM<FPT> h2d::Circle_< FPT >::intersects ( const base::PolylineBase< PLT, FPT2 > &  pl) const
inline

Circle/Polyline intersection.

3497  {
3498  return pl.intersects( * this );
3499  }
Here is the call graph for this function:

◆ isInside() [1/4]

template<typename FPT>
template<typename FPT2 >
bool h2d::Circle_< FPT >::isInside ( const Circle_< FPT2 > &  other) const
inline

Returns true if circle is inside other circle.

3439  {
3440  return( _radius + _center.distTo( other.center() ) < other.radius() );
3441  }
Here is the call graph for this function:
Here is the caller graph for this function:

◆ isInside() [2/4]

template<typename FPT>
template<typename FPT2 >
bool h2d::Circle_< FPT >::isInside ( const Point2d_< FPT2 > &  p1,
const Point2d_< FPT2 > &  p2 
) const
inline

Returns true if circle is inside rectangle defined by p1 and p2.

3446  {
3447  return implC_isInside( detail::getCorrectPoints( p1, p2 ) );
3448  }
PointPair_< FPT > getCorrectPoints(const Point2d_< FPT > &p0, const Point2d_< FPT > &p1)
Private free function, get top-left and bottom-right points from two arbitrary points.
Definition: homog2d.hpp:1346
Here is the call graph for this function:

◆ isInside() [3/4]

template<typename FPT>
template<typename FPT2 >
bool h2d::Circle_< FPT >::isInside ( const FRect_< FPT2 > &  rect) const
inline

Returns true if circle is inside flat rectangle rect.

3453  {
3454  return implC_isInside( rect.getPts() );
3455  }
FRect rect
Definition: homog2d_test.cpp:4038
Here is the call graph for this function:

◆ isInside() [4/4]

template<typename FPT >
template<typename FPT2 , typename PTYPE >
bool h2d::Circle_< FPT >::isInside ( const base::PolylineBase< PTYPE, FPT2 > &  poly) const

Returns true if circle is inside polyline.

Will be true if all these four conditions are met:

  • the polyline object must be of type "closed" AND a polygon (no intersection points)
  • center point is inside the polygon
  • no intersection points
  • any point of the polygon must be outside of the circle
5774 {
5775  HOMOG2D_START;
5776  if( !poly.isSimple() )
5777  return false;
5778  if( poly.getPts()[0].isInside(*this) ) // if a point of the polygon is inside the circle,
5779  return false; // then the circle cannot be inside the polygon
5780 
5781  if( !_center.isInside( poly ) )
5782  return false;
5783 
5784  auto inters = intersects( poly );
5785  return( inters() == 0 );
5786 }
#define HOMOG2D_START
Definition: homog2d.hpp:106
detail::Intersect< detail::Inters_2, FPT > intersects(const Line2d_< FPT2 > &li) const
Circle/Line intersection.
Definition: homog2d.hpp:3469
Here is the call graph for this function:

◆ length()

template<typename FPT>
HOMOG2D_INUMTYPE h2d::Circle_< FPT >::length ( ) const
inlinevirtual

Perimeter of circle.

Implements h2d::rtp::Root.

3311  {
3312  return static_cast<HOMOG2D_INUMTYPE>(_radius) * M_PI * 2.0;
3313  }
#define HOMOG2D_INUMTYPE
Definition: homog2d.hpp:66
#define M_PI
Definition: homog2d.hpp:235
Here is the caller graph for this function:

◆ moveTo() [1/2]

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

Move Circle to other location.

3418  {
3421  set( Point2d_<FPT>(x, y) );
3422  }
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
Here is the caller graph for this function:

◆ moveTo() [2/2]

template<typename FPT>
template<typename T1 >
void h2d::Circle_< FPT >::moveTo ( const Point2d_< T1 > &  pt)
inline

Move Circle to other location, geiven by pt.

3427  {
3428  set( pt );
3429  }
Point2d pt
Definition: homog2d_test.cpp:4034

◆ operator!=()

template<typename FPT>
template<typename FPT2 >
bool h2d::Circle_< FPT >::operator!= ( const Circle_< FPT2 > &  other) const
inline
3531  {
3532  return !( *this == other );
3533  }
Here is the call graph for this function:

◆ operator==()

template<typename FPT>
template<typename FPT2 >
bool h2d::Circle_< FPT >::operator== ( const Circle_< FPT2 > &  other) const
inline
3522  {
3523  if( _radius != other._radius )
3524  return false;
3525  if( _center != other._center )
3526  return false;
3527  return true;
3528  }

◆ radius() [1/2]

template<typename FPT>
FPT& h2d::Circle_< FPT >::radius ( )
inline
3291 { return _radius; }
Here is the caller graph for this function:

◆ radius() [2/2]

template<typename FPT>
const FPT& h2d::Circle_< FPT >::radius ( ) const
inline
3292 { return _radius; }

◆ set() [1/7]

template<typename FPT>
template<typename PT >
void h2d::Circle_< FPT >::set ( const Point2d_< PT > &  center)
inline

Set circle center point, radius unchanged.

3333  {
3334  _center = center;
3335  }
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set() [2/7]

template<typename FPT>
template<typename T , typename std::enable_if<(std::is_arithmetic< T >::value &&!std::is_same< T, bool >::value), T >::type * = nullptr>
void h2d::Circle_< FPT >::set ( rad)
inline

Set circle radius, center point unchanged.

Use of Sfinae so it can be selected only for arithmetic types

3349  {
3350  _radius = rad;
3351  }

◆ set() [3/7]

template<typename FPT>
template<typename FPT2 , typename FPT3 >
void h2d::Circle_< FPT >::set ( const Point2d_< FPT2 > &  center,
FPT3  rad 
)
inline

Set circle from center point and radius.

Todo:
20211216: replace with move
3356  {
3357  Circle_<FPT> c( center, rad );
3358  std::swap( c, *this );
3359  }
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294

◆ set() [4/7]

template<typename FPT>
template<typename FPT2 , typename std::enable_if< std::is_arithmetic< FPT2 >::value, FPT2 >::type * = nullptr>
void h2d::Circle_< FPT >::set ( FPT2  x,
FPT2  y,
FPT2  rad 
)
inline

Set circle from 3 values (x0,y0,radius)

3370  {
3371  set( Point2d_<FPT2>(x,y), rad );
3372  }

◆ set() [5/7]

template<typename FPT >
template<typename T1 , typename T2 >
void h2d::Circle_< FPT >::set ( const Point2d_< T1 > &  pt1,
const Point2d_< T2 > &  pt2 
)

Set circle from 2 points.

5570 {
5571 #ifndef HOMOG2D_NOCHECKS
5572  if( pt1 == pt2 )
5573  HOMOG2D_THROW_ERROR_1( "Unable, some points are identical" );
5574 #endif
5575 
5576  Segment_<HOMOG2D_INUMTYPE> seg( pt1, pt2 );
5577  _center = seg.getCenter();
5578  _radius = seg.length() / 2.0;
5579 }
Segment seg
Definition: homog2d_test.cpp:4033
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
Here is the call graph for this function:

◆ set() [6/7]

template<typename FPT >
template<typename T1 , typename T2 , typename T3 >
void h2d::Circle_< FPT >::set ( const Point2d_< T1 > &  pt1,
const Point2d_< T2 > &  pt2,
const Point2d_< T3 > &  pt3 
)

Set circle from 3 points.

Algorithm: we get the two largest segments and compute their bisector line. Their intersection point will be the center of circle, and the radius is the distance between center and any of the three points.

We consider the the largest segments to improve numerical stability.

Will throw if unable (numerical issue)

One could think that the first checking would be enough, but experience shows that some times, the point are not colinear, but the two bisector lines are still parallel. Thus the second checking.

Todo:
Check this other technique: https://www.johndcook.com/blog/2023/06/18/circle-through-three-points/
5607 {
5608 #ifndef HOMOG2D_NOCHECKS
5609  if( areCollinear( pt1, pt2, pt3 ) )
5610  HOMOG2D_THROW_ERROR_1( "Unable, points are colinear" );
5611 #endif
5612  auto pts = priv::getLargestDistancePoints( pt1, pt2, pt3 );
5613 
5614  auto seg1 = Segment_<HOMOG2D_INUMTYPE>( pts[0], pts[1] );
5615  auto seg2 = Segment_<HOMOG2D_INUMTYPE>( pts[0], pts[2] );
5616  auto li1 = seg1.getBisector();
5617  auto li2 = seg2.getBisector();
5618 #ifndef HOMOG2D_NOCHECKS
5619  if( li1.isParallelTo(li2) )
5620  HOMOG2D_THROW_ERROR_1( "unable, bisector lines are parallel" )
5621 #endif
5622  center() = li1 * li2;
5623  radius() = center().distTo(pt1);
5624 }
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
std::array< PT, 3 > getLargestDistancePoints(PT pt1, PT pt2, PT pt3)
Helper function, used to check for colinearity of three points.
Definition: homog2d.hpp:3613
Point2d_< FPT > & center()
Definition: homog2d.hpp:3294
FPT & radius()
Definition: homog2d.hpp:3291
bool areCollinear(const Point2d_< FPT > &pt1, const Point2d_< FPT > &pt2, const Point2d_< FPT > &pt3)
Returns true if the 3 points are on the same line.
Definition: homog2d.hpp:3684
Here is the call graph for this function:

◆ set() [7/7]

template<typename FPT >
template<typename T , typename std::enable_if< trait::IsContainer< T >::value, T >::type * >
void h2d::Circle_< FPT >::set ( const T &  pts)

Compute circle from a set of points (Minimum Enclosing Circle, aka MEC) using the Welzl algorithm.

T may be std::vector, std::array or std::list holding points

References:

5735 {
5736  if( pts.size() < 2 )
5737  HOMOG2D_THROW_ERROR_1( "unable to build a circle from a single point" );
5738 
5739  if( pts.size() == 2 )
5740  {
5741  set( pts[0], pts[1] );
5742  return;
5743  }
5744 
5745  if( pts.size() == 3 ) // todo: convert pts to HOMOG2D_INUMTYPE
5746  {
5747  set( pts[0], pts[1], pts[2] );
5748  return;
5749  }
5750 
5751  std::vector<Point2d_<HOMOG2D_INUMTYPE>> P_copy( std::begin(pts), std::end(pts) );
5752 // std::random_shuffle( P_copy.begin(), P_copy.end() ); // ? check: what happens if removed?
5753  std::vector<Point2d_<HOMOG2D_INUMTYPE>> R;
5754 
5755  h2d::thr::doNotCheckRadius() = true;
5756  auto cir = p_WelzlHelper( P_copy, R, P_copy.size() );
5757  set( cir.center(), cir.radius() );
5758  h2d::thr::doNotCheckRadius() = false;
5759 }
static bool & doNotCheckRadius()
This one is used for the Welzl minimum enclosing circle.
Definition: homog2d.hpp:1258
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
Circle cir
Definition: homog2d_test.cpp:4036
Here is the call graph for this function:

◆ size()

template<typename FPT>
constexpr size_t h2d::Circle_< FPT >::size ( ) const
inlinevirtual

Implements h2d::rtp::Root.

3299  {
3300  return 1;
3301  }

◆ translate() [1/2]

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

Translate Circle.

3402  {
3405  _center.translate( dx, dy );
3406  }
#define HOMOG2D_CHECK_IS_NUMBER(T)
Definition: homog2d.hpp:144
Here is the call graph for this function:
Here is the caller graph for this function:

◆ translate() [2/2]

template<typename FPT>
template<typename T1 , typename T2 >
void h2d::Circle_< FPT >::translate ( const std::pair< T1, T2 > &  pa)
inline

Translate Circle.

3411  {
3412  this->translate( pa.first, pa.second );
3413  }
void translate(TX dx, TY dy)
Translate Circle.
Definition: homog2d.hpp:3401
Here is the call graph for this function:

◆ type()

template<typename FPT>
Type h2d::Circle_< FPT >::type ( ) const
inlinevirtual

Implements h2d::rtp::Root.

3186  {
3187  return Type::Circle;
3188  }

Friends And Related Function Documentation

◆ Circle_

template<typename FPT>
template<typename T >
friend class Circle_
friend

◆ operator<<

template<typename FPT>
template<typename T >
std::ostream& operator<< ( std::ostream &  f,
const Circle_< T > &  r 
)
friend
8421 {
8422  f << "center: " << r._center << ", radius=" << r._radius;
8423  return f;
8424 }

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