2012-01-25 18:57:23 +00:00
|
|
|
#include "QuadraticUtilities.h"
|
2012-03-27 13:23:51 +00:00
|
|
|
#include <math.h>
|
2012-01-25 18:57:23 +00:00
|
|
|
|
2012-08-21 13:13:52 +00:00
|
|
|
/*
|
|
|
|
|
|
|
|
Numeric Solutions (5.6) suggests to solve the quadratic by computing
|
|
|
|
|
|
|
|
Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C))
|
|
|
|
|
|
|
|
and using the roots
|
|
|
|
|
|
|
|
t1 = Q / A
|
|
|
|
t2 = C / Q
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
2012-01-25 18:57:23 +00:00
|
|
|
int quadraticRoots(double A, double B, double C, double t[2]) {
|
|
|
|
B *= 2;
|
|
|
|
double square = B * B - 4 * A * C;
|
|
|
|
if (square < 0) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
double squareRt = sqrt(square);
|
|
|
|
double Q = (B + (B < 0 ? -squareRt : squareRt)) / -2;
|
|
|
|
int foundRoots = 0;
|
2012-08-21 13:13:52 +00:00
|
|
|
double ratio = Q / A;
|
|
|
|
if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
|
|
|
|
if (ratio < FLT_EPSILON) {
|
|
|
|
ratio = 0;
|
|
|
|
} else if (ratio > 1 - FLT_EPSILON) {
|
|
|
|
ratio = 1;
|
2012-04-17 11:40:34 +00:00
|
|
|
}
|
2012-08-21 13:13:52 +00:00
|
|
|
t[foundRoots++] = ratio;
|
2012-01-25 18:57:23 +00:00
|
|
|
}
|
2012-08-21 13:13:52 +00:00
|
|
|
ratio = C / Q;
|
|
|
|
if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
|
|
|
|
if (ratio < FLT_EPSILON) {
|
|
|
|
ratio = 0;
|
|
|
|
} else if (ratio > 1 - FLT_EPSILON) {
|
|
|
|
ratio = 1;
|
2012-04-17 11:40:34 +00:00
|
|
|
}
|
2012-08-23 15:24:42 +00:00
|
|
|
if (foundRoots == 0 || fabs(t[0] - ratio) >= FLT_EPSILON) {
|
|
|
|
t[foundRoots++] = ratio;
|
|
|
|
}
|
2012-01-25 18:57:23 +00:00
|
|
|
}
|
|
|
|
return foundRoots;
|
|
|
|
}
|
2012-07-02 20:27:02 +00:00
|
|
|
|
|
|
|
void dxdy_at_t(const Quadratic& quad, double t, double& x, double& y) {
|
|
|
|
double a = t - 1;
|
|
|
|
double b = 1 - 2 * t;
|
|
|
|
double c = t;
|
|
|
|
if (&x) {
|
|
|
|
x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
|
|
|
|
}
|
|
|
|
if (&y) {
|
|
|
|
y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void xy_at_t(const Quadratic& quad, double t, double& x, double& y) {
|
|
|
|
double one_t = 1 - t;
|
|
|
|
double a = one_t * one_t;
|
|
|
|
double b = 2 * one_t * t;
|
|
|
|
double c = t * t;
|
|
|
|
if (&x) {
|
|
|
|
x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
|
|
|
|
}
|
|
|
|
if (&y) {
|
|
|
|
y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
|
|
|
|
}
|
|
|
|
}
|