blob: 88524ca9d7345a1c8a75fd96b53ddd747b13b2ee [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.comc899ad92012-08-23 15:24:42 +000042 if (foundRoots == 0 || fabs(t[0] - ratio) >= FLT_EPSILON) {
43 t[foundRoots++] = ratio;
44 }
caryclark@google.com27accef2012-01-25 18:57:23 +000045 }
46 return foundRoots;
47}
caryclark@google.com8dcf1142012-07-02 20:27:02 +000048
49void dxdy_at_t(const Quadratic& quad, double t, double& x, double& y) {
50 double a = t - 1;
51 double b = 1 - 2 * t;
52 double c = t;
53 if (&x) {
54 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
55 }
56 if (&y) {
57 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
58 }
59}
60
61void xy_at_t(const Quadratic& quad, double t, double& x, double& y) {
62 double one_t = 1 - t;
63 double a = one_t * one_t;
64 double b = 2 * one_t * t;
65 double c = t * t;
66 if (&x) {
67 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
68 }
69 if (&y) {
70 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
71 }
72}