blob: cc15bc1444c787ea4d1cac0d3566ceb978844ace [file] [log] [blame]
caryclark@google.com27accef2012-01-25 18:57:23 +00001#include "QuadraticUtilities.h"
caryclark@google.comd88e0892012-03-27 13:23:51 +00002#include <math.h>
caryclark@google.com27accef2012-01-25 18:57:23 +00003
caryclark@google.com03f97062012-08-21 13:13:52 +00004/*
5
6Numeric Solutions (5.6) suggests to solve the quadratic by computing
7
8 Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C))
9
10and using the roots
11
12 t1 = Q / A
13 t2 = C / Q
14
15*/
16
caryclark@google.com27accef2012-01-25 18:57:23 +000017int quadraticRoots(double A, double B, double C, double t[2]) {
18 B *= 2;
19 double square = B * B - 4 * A * C;
20 if (square < 0) {
21 return 0;
22 }
23 double squareRt = sqrt(square);
24 double Q = (B + (B < 0 ? -squareRt : squareRt)) / -2;
25 int foundRoots = 0;
caryclark@google.com03f97062012-08-21 13:13:52 +000026 double ratio = Q / A;
27 if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
28 if (ratio < FLT_EPSILON) {
29 ratio = 0;
30 } else if (ratio > 1 - FLT_EPSILON) {
31 ratio = 1;
caryclark@google.com78e17132012-04-17 11:40:34 +000032 }
caryclark@google.com03f97062012-08-21 13:13:52 +000033 t[foundRoots++] = ratio;
caryclark@google.com27accef2012-01-25 18:57:23 +000034 }
caryclark@google.com03f97062012-08-21 13:13:52 +000035 ratio = C / Q;
36 if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
37 if (ratio < FLT_EPSILON) {
38 ratio = 0;
39 } else if (ratio > 1 - FLT_EPSILON) {
40 ratio = 1;
caryclark@google.com78e17132012-04-17 11:40:34 +000041 }
caryclark@google.com03f97062012-08-21 13:13:52 +000042 t[foundRoots++] = ratio;
caryclark@google.com27accef2012-01-25 18:57:23 +000043 }
44 return foundRoots;
45}
caryclark@google.com8dcf1142012-07-02 20:27:02 +000046
47void dxdy_at_t(const Quadratic& quad, double t, double& x, double& y) {
48 double a = t - 1;
49 double b = 1 - 2 * t;
50 double c = t;
51 if (&x) {
52 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
53 }
54 if (&y) {
55 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
56 }
57}
58
59void xy_at_t(const Quadratic& quad, double t, double& x, double& y) {
60 double one_t = 1 - t;
61 double a = one_t * one_t;
62 double b = 2 * one_t * t;
63 double c = t * t;
64 if (&x) {
65 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
66 }
67 if (&y) {
68 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
69 }
70}