31 #include <config-kig.h> 
   43   double p = polardata.
pdimen;
 
   54   f += a*fx*fx + b*fy*fy + c*fx*fy - d*fx - e*fy;
 
   68   double a = cartdata.
coeffs[0];
 
   69   double b = cartdata.
coeffs[1];
 
   70   double c = cartdata.
coeffs[2];
 
   71   double d = cartdata.
coeffs[3];
 
   72   double e = cartdata.
coeffs[4];
 
   73   double f = cartdata.
coeffs[5];
 
   76   double theta = std::atan2(c, b - a)/2;
 
   79   double costheta = std::cos(theta);
 
   80   double sintheta = std::sin(theta);
 
   82   double aa = a*costheta*costheta + b*sintheta*sintheta - c*sintheta*costheta;
 
   83   double bb = a*sintheta*sintheta + b*costheta*costheta + c*sintheta*costheta;
 
   86     double dd = d*costheta - e*sintheta;
 
   87     double ee = d*sintheta + e*costheta;
 
   88     double xc = - dd / ( 2*aa );
 
   89     double yc = - ee / ( 2*bb );
 
   90     double ff = f + aa*xc*xc + bb*yc*yc + dd*xc + ee*yc;
 
   93       if (theta > 0) theta -= M_PI/2;
 
   95       costheta = cos(theta);
 
   96       sintheta = sin(theta);
 
   97       aa = a*costheta*costheta + b*sintheta*sintheta - c*sintheta*costheta;
 
   98       bb = a*sintheta*sintheta + b*costheta*costheta + c*sintheta*costheta;
 
  103     if ( std::fabs (bb) < std::fabs (aa) )
 
  105       if (theta > 0) theta -= M_PI/2;
 
  106       else theta += M_PI/2;
 
  107       costheta = cos(theta);
 
  108       sintheta = sin(theta);
 
  109       aa = a*costheta*costheta + b*sintheta*sintheta - c*sintheta*costheta;
 
  110       bb = a*sintheta*sintheta + b*costheta*costheta + c*sintheta*costheta;
 
  114   double cc = 2*(a - b)*sintheta*costheta +
 
  115               c*(costheta*costheta - sintheta*sintheta);
 
  117   double dd = d*costheta - e*sintheta;
 
  118   double ee = d*sintheta + e*costheta;
 
  146   double eccentricity = sqrt(1.0 - a);
 
  148   double sqrtdiscrim = sqrt(d*d - 4*a*f);
 
  149   if (d < 0.0) sqrtdiscrim = -sqrtdiscrim;
 
  150   double xf = (4*a*f - 4*f - d*d)/(d + eccentricity*sqrtdiscrim) / 2;
 
  153   focus1.
x = xf*costheta + yf*sintheta;
 
  154   focus1.
y = -xf*sintheta + yf*costheta;
 
  170   const std::vector<Coordinate>& points,
 
  177   assert( 0 < points.size() && points.size() <= 5 );
 
  196   double *matrix[5] = {row0, row1, row2, row3, row4};
 
  201   int numpoints = points.size();
 
  202   int numconstraints = 5;
 
  205   for ( 
int i = 0; i < numpoints; ++i )
 
  207     double xi = points[i].x;
 
  208     double yi = points[i].y;
 
  209     matrix[i][0] = xi*xi;
 
  210     matrix[i][1] = yi*yi;
 
  211     matrix[i][2] = xi*yi;
 
  217   for ( 
int i = 0; i < numconstraints; i++ )
 
  219     if (numpoints >= 5) 
break;    
 
  220     for (
int j = 0; j < 6; ++j) matrix[numpoints][j] = 0.0;
 
  223     if (constraints[i] == 
zerotilt) matrix[numpoints][2] = 1.0;
 
  225     if (constraints[i] == 
parabolaifzt) matrix[numpoints][1] = 1.0;
 
  228       matrix[numpoints][0] = 1.0;
 
  229       matrix[numpoints][1] = -1.0; }
 
  232       matrix[numpoints][0] = 1.0;
 
  233       matrix[numpoints][1] = 1.0; }
 
  235     if (constraints[i] == 
ysymmetry) matrix[numpoints][3] = 1.0;
 
  237     if (constraints[i] == 
xsymmetry) matrix[numpoints][4] = 1.0;
 
  252   const std::vector<Coordinate>& args,
 
  255   assert( args.size() >= 2 && args.size() <= 3 );
 
  256   assert( type == 1 || type == -1 );
 
  263   double eccentricity, d1, d2, dl;
 
  266   double f2f1l = f2f1.
length();
 
  270   if ( args.size() == 3 )
 
  273     d1 = ( d - f1 ).length();
 
  274     d2 = ( d - f2 ).length();
 
  275     dl = fabs( d1 + type * d2 );
 
  276     eccentricity = f2f1l/dl;
 
  280     if ( type > 0 ) eccentricity = 0.7; 
else eccentricity = 2.0;
 
  281     dl = f2f1l/eccentricity;
 
  284   double rhomax = (dl + f2f1l) /2.0;
 
  288   ret.
pdimen = type*(1 - eccentricity)*rhomax;
 
  289   ret.
focus1 = type == 1 ? f1 : f2;
 
  300   double a = data.
coeffs[0];
 
  301   double b = data.
coeffs[1];
 
  302   double c = data.
coeffs[2];
 
  303   double d = data.
coeffs[3];
 
  304   double e = data.
coeffs[4];
 
  305   double f = data.
coeffs[5];
 
  307   double alpha = 2*a*x + c*y + d;
 
  308   double beta = c*x + 2*b*y + e;
 
  309   double gamma = d*x + e*y + 2*f;
 
  311   double normsq = alpha*alpha + beta*beta;
 
  321   Coordinate retb = reta + Coordinate (-beta, alpha);
 
  332   double alpha = p2.
y - p1.
y;
 
  333   double beta = p1.
x - p2.
x;
 
  334   double gamma = p1.
y*p2.
x - p1.
x*p2.
y;
 
  336   double a11 = data.
coeffs[0];
 
  337   double a22 = data.
coeffs[1];
 
  338   double a12 = data.
coeffs[2]/2.0;
 
  339   double a13 = data.
coeffs[3]/2.0;
 
  340   double a23 = data.
coeffs[4]/2.0;
 
  341   double a33 = data.
coeffs[5];
 
  346   double a11inv = a22*a33 - a23*a23;
 
  347   double a22inv = a11*a33 - a13*a13;
 
  348   double a33inv = a11*a22 - a12*a12;
 
  349   double a12inv = a23*a13 - a12*a33;
 
  350   double a23inv = a12*a13 - a23*a11;
 
  351   double a13inv = a12*a23 - a13*a22;
 
  353   double x = a11inv*alpha + a12inv*beta + a13inv*gamma;
 
  354   double y = a12inv*alpha + a22inv*beta + a23inv*gamma;
 
  355   double z = a13inv*alpha + a23inv*beta + a33inv*gamma;
 
  372   assert( which == 1 || which == -1 || which == 0 );
 
  383   double dx = l.
b.
x - l.
a.
x;
 
  384   double dy = l.
b.
y - l.
a.
y;
 
  386   double aaa = aa*dx*dx + bb*dy*dy + cc*dx*dy;
 
  387   double bbb = 2*aa*x*dx + 2*bb*y*dy + cc*x*dy + cc*y*dx + dd*dx + ee*dy;
 
  388   double ccc = aa*x*x + bb*y*y + cc*x*y + dd*x + ee*y + ff;
 
  393     t = - bbb/aaa - knownparam;
 
  394     return l.
a + t*(l.
b - l.
a);
 
  397   double discrim = bbb*bbb - 4*aaa*ccc;
 
  406       t = bbb + which*sqrt(discrim);
 
  409       t = -bbb + which*sqrt(discrim);
 
  417     return l.
a + t*(l.
b - l.
a);
 
  423   double ec, 
double es )
 
  424   : focus1( f ), pdimen( d ), ecostheta0( ec ), esintheta0( es )
 
  429   : focus1(), pdimen( 0 ), ecostheta0( 0 ), esintheta0( 0 )
 
  447   double distpf = (cpoint - cfocus).length();
 
  448   double distpd = ( pa.
y*ba.
x - pa.
x*ba.
y)/bal;
 
  450   double eccentricity = distpf/distpd;
 
  456   ret.
pdimen *= eccentricity;
 
  464   std::copy( incoeffs, incoeffs + 6, 
coeffs );
 
  469   int which, 
bool &valid )
 
  471   assert( which == -1 || which == 1 );
 
  480   double normabc = a*a + b*b + c*c;
 
  481   double delta = c*c - 4*a*b;
 
  482   if (fabs(delta) < 1e-6*normabc) { valid = 
false; 
return ret; }
 
  484   double yc = (2*a*e - c*d)/delta;
 
  485   double xc = (2*b*d - c*e)/delta;
 
  500   double sqrtdelta = sqrt(delta);
 
  503     displacement = 
Coordinate(-2*b, c + sqrtdelta);
 
  505     displacement = 
Coordinate(c + sqrtdelta, -2*a);
 
  507   ret.
b = ret.
a + displacement;
 
  521   double c1 = p1.
x*p2.
y - p2.
x*p1.
y;
 
  522   double b1 = p2.
x - p1.
x;
 
  523   double a1 = p1.
y - p2.
y;
 
  528   double c2 = p1.
x*p2.
y - p2.
x*p1.
y;
 
  529   double b2 = p2.
x - p1.
x;
 
  530   double a2 = p1.
y - p2.
y;
 
  534   double c = a1*b2 + a2*b1;
 
  535   double d = a1*c2 + a2*c1;
 
  536   double e = b1*c2 + c1*b2;
 
  538   double f = a*x*x + b*y*y + c*x*y + d*x + e*y;
 
  546                                  int which, 
int zeroindex, 
bool& valid )
 
  548   assert( which == 1 || which == -1 );
 
  549   assert( 0 < zeroindex && zeroindex < 4 );
 
  553   double a = cequation1.
coeffs[0];
 
  554   double b = cequation1.
coeffs[1];
 
  555   double c = cequation1.
coeffs[2];
 
  556   double d = cequation1.
coeffs[3];
 
  557   double e = cequation1.
coeffs[4];
 
  558   double f = cequation1.
coeffs[5];
 
  560   double a2 = cequation2.
coeffs[0];
 
  561   double b2 = cequation2.
coeffs[1];
 
  562   double c2 = cequation2.
coeffs[2];
 
  563   double d2 = cequation2.
coeffs[3];
 
  564   double e2 = cequation2.
coeffs[4];
 
  565   double f2 = cequation2.
coeffs[5];
 
  574   double df = 4*a*b*f - a*e*e - b*d*d - c*c*f + c*d*e;
 
  575   double cf = 4*a2*b*f + 4*a*b2*f + 4*a*b*f2
 
  576      - 2*a*e*e2 - 2*b*d*d2 - 2*f*c*c2
 
  577      - a2*e*e - b2*d*d - f2*c*c
 
  578      + c2*d*e + c*d2*e + c*d*e2;
 
  579   double bf = 4*a*b2*f2 + 4*a2*b*f2 + 4*a2*b2*f
 
  580      - 2*a2*e2*e - 2*b2*d2*d - 2*f2*c2*c
 
  581      - a*e2*e2 - b*d2*d2 - f*c2*c2
 
  582      + c*d2*e2 + c2*d*e2 + c2*d2*e;
 
  583   double af = 4*a2*b2*f2 - a2*e2*e2 - b2*d2*d2 - c2*c2*f2 + c2*d2*e2;
 
  594   double p1a = 2*bf*bf - 6*cf;
 
  595   double p1b = bf*cf - 9*df;
 
  596   double p0a = cf*p1a*p1a + p1b*(3*p1b - 2*bf*p1a);
 
  597   double fval, fpval, lambda;
 
  599   if (p0a < 0 && p1a < 0)
 
  607   double displace = 1.0;
 
  610     displace += sqrt(p1a);  
 
  616   fval = cf + lambda*fval;         
 
  617   fval = df + lambda*fval;         
 
  619   if (fabs(p0a) < 1e-7)
 
  627     lambda += ( 2 - zeroindex )* displace;
 
  656   const int maxiterations = 30;
 
  657   while (iterations++ < maxiterations)   
 
  661     fval = bf + lambda*fval;         
 
  662     fpval = fval + lambda*fpval;     
 
  663     fval = cf + lambda*fval;         
 
  664     fpval = fval + lambda*fpval;     
 
  665     fval = df + lambda*fval;         
 
  669     if (fabs(delta) < 1e-6) 
break;
 
  671   if (iterations >= maxiterations) { valid = 
false; 
return ret; }
 
  685   df = 4*a*b*f - a*e*e - b*d*d - c*c*f + c*d*e;
 
  689   double dis1 = e*e - 4*b*f;
 
  690   double maxval = fabs(dis1);
 
  692   double dis2 = d*d - 4*a*f;
 
  693   if (fabs(dis2) > maxval)
 
  698   double dis3 = c*c - 4*a*b;
 
  699   if (fabs(dis3) > maxval)
 
  711     temp = a; a = f; f = temp;
 
  712     temp = c; c = e; e = temp;
 
  713     temp = dis1; dis1 = dis3; dis3 = temp;
 
  717     temp = b; b = f; f = temp;
 
  718     temp = c; c = d; d = temp;
 
  719     temp = dis2; dis2 = dis3; dis3 = temp;
 
  752     temp = a; a = f; f = temp;
 
  753     temp = c; c = e; e = temp;
 
  754     temp = dis1; dis1 = dis3; dis3 = temp;
 
  755     temp = r[0]; r[0] = r[2]; r[2] = temp;
 
  759     temp = b; b = f; f = temp;
 
  760     temp = c; c = d; d = temp;
 
  761     temp = dis2; dis2 = dis3; dis3 = temp;
 
  762     temp = r[1]; r[1] = r[2]; r[2] = temp;
 
  770   double rnormsq = r[0]*r[0] + r[1]*r[1] + r[2]*r[2];
 
  771   double k = sqrt( rnormsq );
 
  772   if ( k*r[2] < 0) k = -k;
 
  773   double wnorm = sqrt( 2*rnormsq + 2*k*r[2] );
 
  776   w[2] = (r[2] + k)/wnorm;
 
  782   double q0 = a*w[0] + c*w[1]/2 + d*w[2]/2;
 
  783   double q1 = b*w[1] + c*w[0]/2 + e*w[2]/2;
 
  784   double alpha = a*w[0]*w[0] + b*w[1]*w[1] + c*w[0]*w[1] +
 
  785                  d*w[0]*w[2] + e*w[1]*w[2] + f*w[2]*w[2];
 
  786   double a00 = a - 4*w[0]*q0 + 4*w[0]*w[0]*alpha;
 
  787   double a11 = b - 4*w[1]*q1 + 4*w[1]*w[1]*alpha;
 
  788   double a01 = c/2 - 2*w[1]*q0 - 2*w[0]*q1 + 4*w[0]*w[1]*alpha;
 
  790   double dis = a01*a01 - a00*a11;
 
  792   double sqrtdis = sqrt( dis );
 
  796     px = a01 + which*sqrtdis;
 
  800     py = a01 - which*sqrtdis;
 
  803   double pscalw = w[0]*px + w[1]*py;
 
  804   p[0] = px - 2*pscalw*w[0];
 
  805   p[1] = py - 2*pscalw*w[1];
 
  806   p[2] =    - 2*pscalw*w[2];
 
  819   ret.
a = -p[2]/(p[0]*p[0] + p[1]*p[1]) * 
Coordinate (p[0],p[1]);
 
  834   a[1][2] = a[2][1] = data.
coeffs[2]/2;
 
  835   a[0][1] = a[1][0] = data.
coeffs[3]/2;
 
  836   a[0][2] = a[2][0] = data.
coeffs[4]/2;
 
  842   double supnorm = 0.0;
 
  843   for (
int i = 0; i < 3; i++)
 
  845     for (
int j = 0; j < 3; j++)
 
  848       for (
int ii = 0; ii < 3; ii++)
 
  850         for (
int jj = 0; jj < 3; jj++)
 
  852       b[i][j] += a[ii][jj]*ti.
data( ii, i )*ti.
data( jj, j );
 
  855       if ( std::fabs( b[i][j] ) > supnorm ) supnorm = std::fabs( b[i][j] );
 
  859   for (
int i = 0; i < 3; i++)
 
  861     for (
int j = 0; j < 3; j++)
 
  868                               b[0][1] + b[1][0], b[0][2] + b[2][0], b[0][0] );
 
  892   return finite( 
coeffs[0] );
 
const LineData calcConicPolarLine(const ConicCartesianData &data, const Coordinate &cpole, bool &valid)
This function calculates the polar line of the point cpole with respect to the given conic data...
 
LinearConstraints
These are the constraint values that can be passed to the calcConicThroughPoints function. 
 
double esintheta0
The esintheta0 value from the polar equation. 
 
Simple class representing a line. 
 
const Coordinate dir() const 
The direction of the line. 
 
Coordinate b
Another point on the line. 
 
const LineData calcConicAsymptote(const ConicCartesianData data, int which, bool &valid)
This function calculates the asymptote of the given conic ( data ). 
 
const ConicCartesianData calcConicThroughPoints(const std::vector< Coordinate > &points, const LinearConstraints c1, const LinearConstraints c2, const LinearConstraints c3, const LinearConstraints c4, const LinearConstraints c5)
Calculate a conic through a given set of points. 
 
const Coordinate calcConicPolarPoint(const ConicCartesianData &data, const LineData &polar)
This function calculates the polar point of the line polar with respect to the given conic data...
 
static ConicCartesianData invalidData()
Invalid conic. 
 
The Coordinate class is the basic class representing a 2D location by its x and y components...
 
double length() const 
Length. 
 
bool GaussianElimination(double *matrix[], int numrows, int numcols, int exchange[])
Gaussian Elimination. 
 
const ConicPolarData calcConicBDFP(const LineData &directrix, const Coordinate &cfocus, const Coordinate &cpoint)
function used by ConicBDFP. 
 
const Coordinate calcConicLineIntersect(const ConicCartesianData &c, const LineData &l, double knownparam, int which)
This function calculates the intersection of a given line ( l ) and a given conic ( c )...
 
Coordinate focus1
The first focus of this conic. 
 
const LineData calcConicRadical(const ConicCartesianData &cequation1, const ConicCartesianData &cequation2, int which, int zeroindex, bool &valid)
This function calculates the radical line of two conics. 
 
Coordinate a
One point on the line. 
 
double pdimen
The pdimen value from the polar equation. 
 
double ecostheta0
The ecostheta0 value from the polar equation. 
 
static Coordinate invalidCoord()
Create an invalid Coordinate. 
 
const ConicPolarData calcConicBFFP(const std::vector< Coordinate > &args, int type)
This function is used by ConicBFFP. 
 
bool operator==(const ConicPolarData &lhs, const ConicPolarData &rhs)
 
const ConicCartesianData calcConicByAsymptotes(const LineData &line1, const LineData &line2, const Coordinate &p)
This calcs the hyperbola defined by its two asymptotes line1 and line2, and a point p on the edge...
 
bool valid() const 
Test validity. 
 
void BackwardSubstitution(double *matrix[], int numrows, int numcols, int exchange[], double solution[])
 
const ConicCartesianData calcConicTransformation(const ConicCartesianData &data, const Transformation &t, bool &valid)
This calculates the image of the given conic ( data ) through the given transformation ( t )...
 
This class represents an equation of a conic in the form .