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)

3166  : _radius(1.)
3167  {}
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)

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

◆ 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

3184  : Circle_( center, 1. )
3185  {}
Circle_()
Default constructor, unit-radius circle at (0,0)
Definition: homog2d.hpp:3166
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259

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

3197  {
3198  set( pts );
3199  }

◆ 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

3204  : _radius(rad), _center(center)
3205  {
3206 #ifndef HOMOG2D_NOCHECKS
3208  HOMOG2D_THROW_ERROR_1( "radius value too small: " << std::scientific << homog2d_abs(rad) );
3209  if( rad < 0. )
3210  HOMOG2D_THROW_ERROR_1( "radius must not be <0" );
3211 #endif
3212  }
static HOMOG2D_INUMTYPE & nullDistance()
Definition: homog2d.hpp:1195
#define homog2d_abs
Definition: homog2d.hpp:69
static bool & doNotCheckRadius()
This one is used for the Welzl minimum enclosing circle.
Definition: homog2d.hpp:1224
#define HOMOG2D_THROW_ERROR_1(msg)
Error throw wrapper macro.
Definition: homog2d.hpp:181
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259
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)

3217  {
3218  set( pt1, pt2 );
3219  }
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)

3234  : Circle_( Point2d_<FPT>(x,y), rad )
3235  {
3236 // HOMOG2D_CHECK_IS_NUMBER(T1); // not needed, done by sfinae above
3238  }
Circle_()
Default constructor, unit-radius circle at (0,0)
Definition: homog2d.hpp:3166
#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

3243  {
3244  set( pt1, pt2, pt3 );
3245  }

◆ Circle_() [9/9]

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

Copy-Constructor.

3250  : _radius(other._radius), _center(other._center)
3251  {}

Member Function Documentation

◆ area()

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

Area of circle.

Implements h2d::rtp::Root.

3270  {
3271  return static_cast<HOMOG2D_INUMTYPE>(_radius) * _radius * M_PI;
3272  }
#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
3259 { 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
3260 { 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.

11908 {
11909  cv::circle(
11910  im.getReal(),
11911  _center.getCvPti(),
11912  static_cast<int>(_radius),
11913  dp.cvColor(),
11914  dp._dpValues._lineThickness,
11915  dp._dpValues._lineType==1?cv::LINE_AA:cv::LINE_8
11916  );
11917  if( dp._dpValues._showPoints )
11918  // WARNING: can't use the "Dot" style here, because it call this function, so infinite recursion
11919  _center.draw( im, dp.setPointStyle( img::PtStyle::Plus) );
11920 }
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.

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

◆ getBB()

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

Returns Bounding Box of circle.

3282  {
3283  return FRect_<HOMOG2D_INUMTYPE>(
3284  static_cast<HOMOG2D_INUMTYPE>( _center.getX() ) - _radius,
3285  static_cast<HOMOG2D_INUMTYPE>( _center.getY() ) - _radius,
3286  static_cast<HOMOG2D_INUMTYPE>( _center.getX() ) + _radius,
3287  static_cast<HOMOG2D_INUMTYPE>( _center.getY() ) + _radius
3288  );
3289  }
#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
3261 { 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.

3435  {
3436  return li.intersects( *this );
3437  }
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.

3443  {
3444  return seg.intersects( *this );
3445  }
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.
5802 {
5803  if( *this == other )
5804  return detail::IntersectM<FPT>();
5805 
5806  HOMOG2D_INUMTYPE r1 = _radius;
5807  HOMOG2D_INUMTYPE r2 = other._radius;
5808  Point2d_<HOMOG2D_INUMTYPE> pt1 = _center;
5809  Point2d_<HOMOG2D_INUMTYPE> pt2 = other._center;
5810 
5811  HOMOG2D_INUMTYPE x1 = pt1.getX();
5812  HOMOG2D_INUMTYPE y1 = pt1.getY();
5813  HOMOG2D_INUMTYPE x2 = pt2.getX();
5814  HOMOG2D_INUMTYPE y2 = pt2.getY();
5815  HOMOG2D_INUMTYPE d_squared = (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2);
5816 
5817  if( d_squared > r1*r1 + r2*r2 + (HOMOG2D_INUMTYPE)2.*r1*r2 ) // no intersection
5818  return detail::IntersectM<FPT>();
5819 
5820  if( d_squared < ( r1*r1 + r2*r2 - (HOMOG2D_INUMTYPE)2.*r1*r2 ) ) // no intersection: one circle inside the other
5821  return detail::IntersectM<FPT>();
5822 
5823  auto d = homog2d_sqrt( d_squared );
5824  auto a = (r1*r1 - r2*r2 + d_squared) / (HOMOG2D_INUMTYPE)2. / d;
5825  auto h = homog2d_sqrt( r1*r1 - a*a );
5826 
5827  Point2d_<FPT> P0(
5828  ( x2 - x1 ) * a / d + x1,
5829  ( y2 - y1 ) * a / d + y1
5830  );
5831 
5832  Point2d_<FPT> pt3(
5833  P0.getX() + ( y1 - y2 ) * h / d,
5834  P0.getY() - ( x1 - x2 ) * h / d
5835  );
5836  Point2d_<FPT> pt4(
5837  P0.getX() - ( y1 - y2 ) * h / d,
5838  P0.getY() + ( x1 - x2 ) * h / d
5839  );
5840 
5841  detail::IntersectM<FPT> out;
5842  out.add( pt3 );
5843  if( pt3 != pt4 )
5844  out.add( pt4 );
5845  return out;
5846 }
#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.

3455  {
3456  return rect.intersects( * this );
3457  }
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.

3462  {
3463  return pl.intersects( * this );
3464  }
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.

3404  {
3405  return( _radius + _center.distTo( other.center() ) < other.radius() );
3406  }
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.

3411  {
3412  return implC_isInside( detail::getCorrectPoints( p1, p2 ) );
3413  }
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:1312
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.

3418  {
3419  return implC_isInside( rect.getPts() );
3420  }
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
5773 {
5774  HOMOG2D_START;
5775  if( !poly.isSimple() )
5776  return false;
5777  if( poly.getPts()[0].isInside(*this) ) // if a point of the polygon is inside the circle,
5778  return false; // then the circle cannot be inside the polygon
5779 
5780  if( !_center.isInside( poly ) )
5781  return false;
5782 
5783  auto inters = intersects( poly );
5784  return( inters() == 0 );
5785 }
#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:3434
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.

3276  {
3277  return static_cast<HOMOG2D_INUMTYPE>(_radius) * M_PI * 2.0;
3278  }
#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.

3383  {
3386  set( Point2d_<FPT>(x, y) );
3387  }
#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.

3392  {
3393  set( pt );
3394  }
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
3496  {
3497  return !( *this == other );
3498  }
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
3487  {
3488  if( _radius != other._radius )
3489  return false;
3490  if( _center != other._center )
3491  return false;
3492  return true;
3493  }

◆ radius() [1/2]

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

◆ radius() [2/2]

template<typename FPT>
const FPT& h2d::Circle_< FPT >::radius ( ) const
inline
3257 { 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.

3298  {
3299  _center = center;
3300  }
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259
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

3314  {
3315  _radius = rad;
3316  }

◆ 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
3321  {
3322  Circle_<FPT> c( center, rad );
3323  std::swap( c, *this );
3324  }
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259

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

3335  {
3336  set( Point2d_<FPT2>(x,y), rad );
3337  }

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

5569 {
5570 #ifndef HOMOG2D_NOCHECKS
5571  if( pt1 == pt2 )
5572  HOMOG2D_THROW_ERROR_1( "Unable, some points are identical" );
5573 #endif
5574 
5575  Segment_<HOMOG2D_INUMTYPE> seg( pt1, pt2 );
5576  _center = seg.getCenter();
5577  _radius = seg.length() / 2.0;
5578 }
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/
5606 {
5607 #ifndef HOMOG2D_NOCHECKS
5608  if( areCollinear( pt1, pt2, pt3 ) )
5609  HOMOG2D_THROW_ERROR_1( "Unable, points are colinear" );
5610 #endif
5611  auto pts = priv::getLargestDistancePoints( pt1, pt2, pt3 );
5612 
5613  auto seg1 = Segment_<HOMOG2D_INUMTYPE>( pts[0], pts[1] );
5614  auto seg2 = Segment_<HOMOG2D_INUMTYPE>( pts[0], pts[2] );
5615  auto li1 = seg1.getBisector();
5616  auto li2 = seg2.getBisector();
5617 #ifndef HOMOG2D_NOCHECKS
5618  if( li1.isParallelTo(li2) )
5619  HOMOG2D_THROW_ERROR_1( "unable, bisector lines are parallel" )
5620 #endif
5621  center() = li1 * li2;
5622  radius() = center().distTo(pt1);
5623 }
#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:3578
Point2d_< FPT > & center()
Definition: homog2d.hpp:3259
FPT & radius()
Definition: homog2d.hpp:3256
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:3649
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:

5734 {
5735  if( pts.size() < 2 )
5736  HOMOG2D_THROW_ERROR_1( "unable to build a circle from a single point" );
5737 
5738  if( pts.size() == 2 )
5739  {
5740  set( pts[0], pts[1] );
5741  return;
5742  }
5743 
5744  if( pts.size() == 3 ) // todo: convert pts to HOMOG2D_INUMTYPE
5745  {
5746  set( pts[0], pts[1], pts[2] );
5747  return;
5748  }
5749 
5750  std::vector<Point2d_<HOMOG2D_INUMTYPE>> P_copy( std::begin(pts), std::end(pts) );
5751 // std::random_shuffle( P_copy.begin(), P_copy.end() ); // ? check: what happens if removed?
5752  std::vector<Point2d_<HOMOG2D_INUMTYPE>> R;
5753 
5754  h2d::thr::doNotCheckRadius() = true;
5755  auto cir = p_WelzlHelper( P_copy, R, P_copy.size() );
5756  set( cir.center(), cir.radius() );
5757  h2d::thr::doNotCheckRadius() = false;
5758 }
static bool & doNotCheckRadius()
This one is used for the Welzl minimum enclosing circle.
Definition: homog2d.hpp:1224
#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.

3264  {
3265  return 1;
3266  }

◆ translate() [1/2]

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

Translate Circle.

3367  {
3370  _center.translate( dx, dy );
3371  }
#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.

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

◆ type()

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

Implements h2d::rtp::Root.

3151  {
3152  return Type::Circle;
3153  }

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
8420 {
8421  f << "center: " << r._center << ", radius=" << r._radius;
8422  return f;
8423 }

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