All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Defines
#include <Circle.h>
Public Member Functions | |
Circle (double x0=0.0, double y0=0.0, double r=0.0) | |
Circle (const Point2D &c, double r) | |
Circle (const Circle &o) | |
double | distanceTo (const Point2D &p) const |
QVector< Point2D > | intersect (const Circle &o) const |
Point2D | intersect (const Circle &o, bool &ok, const Circle &disc) const |
virtual | ~Circle () |
QGpCoreTools::Circle::Circle | ( | double | x0 = 0.0 , |
double | y0 = 0.0 , |
||
double | r = 0.0 |
||
) |
{ _x0=x0; _y0=y0; _r=fabs(r); }
QGpCoreTools::Circle::Circle | ( | const Point2D & | c, |
double | r | ||
) |
References QGpCoreTools::Point2D::x(), and QGpCoreTools::Point2D::y().
{ _x0=c.x(); _y0=c.y(); _r=fabs(r); }
QGpCoreTools::Circle::Circle | ( | const Circle & | o | ) |
{ _x0=o._x0; _y0=o._y0; _r=o._r; }
virtual QGpCoreTools::Circle::~Circle | ( | ) | [inline, virtual] |
{}
double QGpCoreTools::Circle::distanceTo | ( | const Point2D & | p | ) | const |
References QGpCoreTools::Point2D::distanceTo(), and TRACE.
Referenced by intersect().
{ TRACE; double d=p.distanceTo(Point2D(_x0,_y0)); return fabs(d-_r); }
QVector< Point2D > QGpCoreTools::Circle::intersect | ( | const Circle & | o | ) | const |
Calculate intersections between this and o.
References A, QGpCoreTools::sqrt(), and TRACE.
Referenced by TapePositioningSystem::Cluster::add(), intersect(), and QGpCoreTools::PointLocate::position().
{ TRACE; QVector<Point2D> inter; double r02=_r*_r; double r12=o._r*o._r; double x02=_x0*_x0; double y02=_y0*_y0; double x12=o._x0*o._x0; double y12=o._y0*o._y0; double a,b,c,rho,srho,A,B,C,D; A=2.0 * (o._x0-_x0); B=2.0 * (o._y0-_y0); C=r02 - r12 - (x02 + y02 - x12 - y12); // The solution must satisfy // A * xs + B * ys=C, which is simply the subtraction of circle equations if(fabs(A)>fabs(B)) { // Prefer working with xs=(C-B*ys)/A transformed into xs=B-A*ys, with B=C/A and A=B/A D=1.0/A; A=B*D; B=C*D; a=1.0+A*A; b=2*A*_x0-2*A*B-2*_y0; c=x02+B*B-2*_x0*B+y02-r02; rho=b*b-4*a*c; if(rho>0) { srho=::sqrt(rho); inter.resize(2); inter[0].setY((-b+srho)/(2.0*a)); inter[1].setY((-b-srho)/(2.0*a)); inter[0].setX(B-A*inter[0].y()); inter[1].setX(B-A*inter[1].y()); // Check: //printf("Check c1 %lf==%lf\n",_r,sqrt((inter[0].x()-_x0)*(inter[0].x()-_x0)+(inter[0].y()-_y0)*(inter[0].y()-_y0))); //printf("Check c2 %lf==%lf\n",o._r,sqrt((inter[0].x()-o._x0)*(inter[0].x()-o._x0)+(inter[0].y()-o._y0)*(inter[0].y()-o._y0))); } else if(rho==0) { inter.resize(1); inter[0].setY( -b/a); inter[0].setX(B-A*inter[0].y()); } } else { // Prefer working with ys=(C-A*xs)/B transformed into ys=B-A*xs, with B=C/A and A=B/A D=1.0/B; A=A*D; B=C*D; a=1.0+A*A; b=2*A*_y0-2*A*B-2*_x0; c=x02+B*B-2*_y0*B+y02-r02; rho=b*b-4*a*c; if(rho>0) { srho=::sqrt(rho); inter.resize(2); inter[0].setX((-b+srho)/(2.0*a)); inter[1].setX((-b-srho)/(2.0*a)); inter[0].setY(B-A*inter[0].x()); inter[1].setY(B-A*inter[1].x()); } else if(rho==0) { inter.resize(1); inter[0].setX( -b/a); inter[0].setY(B-A*inter[0].x()); } } return inter; }
Point2D QGpCoreTools::Circle::intersect | ( | const Circle & | o, |
bool & | ok, | ||
const Circle & | disc | ||
) | const |
For convenience returns only one solution. If two solution are found only the closest to disc is returned. If no solution is found, ok is set to false.
References distanceTo(), intersect(), and TRACE.
{ TRACE; QVector<Point2D> solutions=intersect(o); switch(solutions.count()) { case 1: ok=true; return solutions[0]; case 2: ok=true; if(disc.distanceTo(solutions[0])<disc.distanceTo(solutions[1])) return solutions[0]; else return solutions[1]; default: ok=false; return Point2D(); } }