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)