22 #include <config-kig.h> 
   38             const double incoeffs[10] )
 
   40   std::copy( incoeffs, incoeffs + 10, 
coeffs );
 
   47   for ( 
int i = 0; i < 10; ++i )
 
   49     if ( std::fabs( 
coeffs[i] ) > norm ) norm = std::fabs( 
coeffs[i] );
 
   51   if ( norm < 1e-8 ) 
return;
 
   52   for ( 
int i = 0; i < 10; ++i )
 
   59     const std::vector<Coordinate>& points )
 
   82   double *matrix[9] = {row0, row1, row2, row3, row4, row5, row6, row7, row8};
 
   86   int numpoints = points.size();
 
   87   int numconstraints = 9;
 
   90   for ( 
int i = 0; i < numpoints; ++i )
 
   92     double xi = points[i].x;
 
   93     double yi = points[i].y;
 
  100     matrix[i][6] = xi*xi*xi;
 
  101     matrix[i][7] = xi*xi*yi;
 
  102     matrix[i][8] = xi*yi*yi;
 
  103     matrix[i][9] = yi*yi*yi;
 
  106   for ( 
int i = 0; i < numconstraints; i++ )
 
  108     if (numpoints >= 9) 
break;    
 
  109     for (
int j = 0; j < 10; ++j) matrix[numpoints][j] = 0.0;
 
  110     bool addedconstraint = 
true;
 
  114         matrix[numpoints][7] = 1.0;
 
  115         matrix[numpoints][8] = -1.0;
 
  118         matrix[numpoints][7] = 1.0;
 
  121         matrix[numpoints][9] = 1.0;
 
  124         matrix[numpoints][4] = 1.0;
 
  127         matrix[numpoints][5] = 1.0;
 
  130         matrix[numpoints][3] = 1.0;
 
  133         matrix[numpoints][1] = 1.0;
 
  137         addedconstraint = 
false;
 
  141     if (addedconstraint) ++numpoints;
 
  154     const std::vector<Coordinate>& points )
 
  170   double *matrix[9] = {row0, row1, row2, row3, row4, row5, row6, row7, row8};
 
  174   int numpoints = points.size();
 
  175   int numconstraints = 9;
 
  178   for ( 
int i = 0; i < numpoints; ++i )
 
  180     double xi = points[i].x;
 
  181     double yi = points[i].y;
 
  185     matrix[i][3] = xi*xi;
 
  186     matrix[i][4] = xi*yi;
 
  187     matrix[i][5] = yi*yi;
 
  188     matrix[i][6] = xi*xi*xi;
 
  189     matrix[i][7] = xi*xi*yi;
 
  190     matrix[i][8] = xi*yi*yi;
 
  191     matrix[i][9] = yi*yi*yi;
 
  194   for ( 
int i = 0; i < numconstraints; i++ )
 
  196     if (numpoints >= 9) 
break;    
 
  197     for (
int j = 0; j < 10; ++j) matrix[numpoints][j] = 0.0;
 
  198     bool addedconstraint = 
true;
 
  202     matrix[numpoints][0] = 1.0;   
 
  205     matrix[numpoints][1] = 1.0;
 
  208     matrix[numpoints][2] = 1.0;   
 
  211         matrix[numpoints][3] = 1.0;   
 
  214         matrix[numpoints][4] = 1.0;   
 
  217         matrix[numpoints][7] = 1.0;
 
  218         matrix[numpoints][8] = -1.0;
 
  221         matrix[numpoints][7] = 1.0;
 
  224         matrix[numpoints][9] = 1.0;
 
  227         matrix[numpoints][6] = 1.0;
 
  231         addedconstraint = 
false;
 
  235     if (addedconstraint) ++numpoints;
 
  248     const std::vector<Coordinate>& points )
 
  264   double *matrix[9] = {row0, row1, row2, row3, row4, row5, row6, row7, row8};
 
  268   int numpoints = points.size();
 
  269   int numconstraints = 9;
 
  272   for ( 
int i = 0; i < numpoints; ++i )
 
  274     double xi = points[i].x;
 
  275     double yi = points[i].y;
 
  279     matrix[i][3] = xi*xi;
 
  280     matrix[i][4] = xi*yi;
 
  281     matrix[i][5] = yi*yi;
 
  282     matrix[i][6] = xi*xi*xi;
 
  283     matrix[i][7] = xi*xi*yi;
 
  284     matrix[i][8] = xi*yi*yi;
 
  285     matrix[i][9] = yi*yi*yi;
 
  288   for ( 
int i = 0; i < numconstraints; i++ )
 
  290     if (numpoints >= 9) 
break;    
 
  291     for (
int j = 0; j < 10; ++j) matrix[numpoints][j] = 0.0;
 
  292     bool addedconstraint = 
true;
 
  296     matrix[numpoints][0] = 1.0;
 
  299     matrix[numpoints][1] = 1.0;
 
  302     matrix[numpoints][2] = 1.0;
 
  305         matrix[numpoints][7] = 1.0;
 
  306         matrix[numpoints][8] = -1.0;
 
  309         matrix[numpoints][7] = 1.0;
 
  312         matrix[numpoints][9] = 1.0;
 
  315         matrix[numpoints][4] = 1.0;
 
  318         matrix[numpoints][5] = 1.0;
 
  321         matrix[numpoints][3] = 1.0;
 
  325         addedconstraint = 
false;
 
  329     if (addedconstraint) ++numpoints;
 
  352   double a000 = data.
coeffs[0];
 
  353   double a001 = data.
coeffs[1];
 
  354   double a002 = data.
coeffs[2];
 
  355   double a011 = data.
coeffs[3];
 
  356   double a012 = data.
coeffs[4];
 
  357   double a022 = data.
coeffs[5];
 
  358   double a111 = data.
coeffs[6];
 
  359   double a112 = data.
coeffs[7];
 
  360   double a122 = data.
coeffs[8];
 
  361   double a222 = data.
coeffs[9];
 
  366   double b = a122*x + a022;
 
  368   double c = a112*x*x + a012*x + a002;
 
  370   double d = a111*x*x*x + a011*x*x + a001*x + a000;
 
  372   return calcCubicRoot ( ymin, ymax, a, b, c, d, root, valid, numroots );
 
  377                                          int root, 
bool& valid )
 
  379   assert( root == 1 || root == 2 || root == 3 );
 
  385     calcCubicRoot ( -1e10, 1e10, a, b, c, d, root, valid, numroots );
 
  386   return l.
a + param*(l.
b - l.
a);
 
  397                                 double& a, 
double& b, 
double& c, 
double& d )
 
  401   double a000 = data.
coeffs[0];
 
  402   double a001 = data.
coeffs[1];
 
  403   double a002 = data.
coeffs[2];
 
  404   double a011 = data.
coeffs[3];
 
  405   double a012 = data.
coeffs[4];
 
  406   double a022 = data.
coeffs[5];
 
  407   double a111 = data.
coeffs[6];
 
  408   double a112 = data.
coeffs[7];
 
  409   double a122 = data.
coeffs[8];
 
  410   double a222 = data.
coeffs[9];
 
  416   d += a001*p.
x + a002*p.
y;
 
  417   c += a001*v.
x + a002*v.
y;
 
  420   d +=   a011*p.
x*p.
x + a012*p.
x*p.
y             +   a022*p.
y*p.
y;
 
  421   c += 2*a011*p.
x*v.
x + a012*(p.
x*v.
y + v.
x*p.
y) + 2*a022*p.
y*v.
y;
 
  422   b +=   a011*v.
x*v.
x + a012*v.
x*v.
y             +   a022*v.
y*v.
y;
 
  425   d +=    a111*p.
x*p.
x*p.
x + a222*p.
y*p.
y*p.
y;
 
  426   c += 3*(a111*p.
x*p.
x*v.
x + a222*p.
y*p.
y*v.
y);
 
  427   b += 3*(a111*p.
x*v.
x*v.
x + a222*p.
y*v.
y*v.
y);
 
  428   a +=    a111*v.
x*v.
x*v.
x + a222*v.
y*v.
y*v.
y;
 
  431   d += a112*p.
x*p.
x*p.
y + a122*p.
x*p.
y*p.
y;
 
  432   c += a112*(p.
x*p.
x*v.
y + 2*p.
x*v.
x*p.
y) + a122*(v.
x*p.
y*p.
y + 2*p.
x*p.
y*v.
y);
 
  433   b += a112*(v.
x*v.
x*p.
y + 2*v.
x*p.
x*v.
y) + a122*(p.
x*v.
y*v.
y + 2*v.
x*v.
y*p.
y);
 
  434   a += a112*v.
x*v.
x*v.
y + a122*v.
x*v.
y*v.
y;
 
  447   for (
int i=0; i < 3; i++)
 
  449     for (
int j=i; j < 3; j++)
 
  451       for (
int k=j; k < 3; k++)
 
  453     a[i][j][k] = data.
coeffs[icount++];
 
  459         a[i][k][i] = a[k][i][i] = a[i][i][k];
 
  464         a[j][i][j] = a[j][j][i] = a[i][j][j];
 
  469         a[i][k][j] = a[j][i][k] = a[j][k][i] =
 
  470                          a[k][i][j] = a[k][j][i] = a[i][j][k];
 
  478   if ( ! valid ) 
return dataout;
 
  480   for (
int i = 0; i < 3; i++)
 
  482     for (
int j = 0; j < 3; j++)
 
  484       for (
int k = 0; k < 3; k++)
 
  487         for (
int ii = 0; ii < 3; ii++)
 
  489           for (
int jj = 0; jj < 3; jj++)
 
  491             for (
int kk = 0; kk < 3; kk++)
 
  493           b[i][j][k] += a[ii][jj][kk]*ti.
data( ii, i )*ti.
data( jj, j )*ti.
data( kk, k );
 
  510   dataout.
coeffs[0] = b[0][0][0];
 
  511   dataout.
coeffs[1] = b[0][0][1] + b[0][1][0] + b[1][0][0];
 
  512   dataout.
coeffs[2] = b[0][0][2] + b[0][2][0] + b[2][0][0];
 
  513   dataout.
coeffs[3] = b[0][1][1] + b[1][0][1] + b[1][1][0];
 
  514   dataout.
coeffs[4] = b[0][1][2] + b[0][2][1] + b[1][2][0] + b[1][0][2] + b[2][1][0] + b[2][0][1];
 
  515   dataout.
coeffs[5] = b[0][2][2] + b[2][0][2] + b[2][2][0];
 
  516   dataout.
coeffs[6] = b[1][1][1];
 
  517   dataout.
coeffs[7] = b[1][1][2] + b[1][2][1] + b[2][1][1];
 
  518   dataout.
coeffs[8] = b[1][2][2] + b[2][1][2] + b[2][2][1];
 
  519   dataout.
coeffs[9] = b[2][2][2];
 
  526   for ( 
int i = 0; i < 10; ++i )
 
  541   return finite( 
coeffs[0] );
 
void calcCubicLineRestriction(CubicCartesianData data, Coordinate p, Coordinate v, double &a, double &b, double &c, double &d)
double calcCubicRoot(double xmin, double xmax, double a, double b, double c, double d, int root, bool &valid, int &numroots)
This file is part of Kig, a KDE program for Interactive Geometry... 
const CubicCartesianData calcCubicCuspThroughPoints(const std::vector< Coordinate > &points)
Simple class representing a line. 
Coordinate b
Another point on the line. 
CubicCartesianData()
Default Constructor. 
The Coordinate class is the basic class representing a 2D location by its x and y components...
bool GaussianElimination(double *matrix[], int numrows, int numcols, int exchange[])
Gaussian Elimination. 
double calcCubicYvalue(double x, double ymin, double ymax, int root, CubicCartesianData data, bool &valid, int &numroots)
bool valid() const 
Return whether this is a valid CubicCartesianData. 
Coordinate a
One point on the line. 
This class represents an equation of a cubic in the form  (in homogeneous coordinates, ), . 
const CubicCartesianData calcCubicNodeThroughPoints(const std::vector< Coordinate > &points)
const Coordinate calcCubicLineIntersect(const CubicCartesianData &cu, const LineData &l, int root, bool &valid)
void BackwardSubstitution(double *matrix[], int numrows, int numcols, int exchange[], double solution[])
const CubicCartesianData calcCubicThroughPoints(const std::vector< Coordinate > &points)
This function calcs a cartesian cubic equation such that the given points are on the cubic...
bool operator==(const CubicCartesianData &lhs, const CubicCartesianData &rhs)
static CubicCartesianData invalidData()
Create an invalid CubicCartesianData. 
const CubicCartesianData calcCubicTransformation(const CubicCartesianData &data, const Transformation &t, bool &valid)