blob: 43bd0135f45555319b59f791336d092b9c239614 [file] [log] [blame]
caryclark@google.com9e49fb62012-08-27 14:11:33 +00001/*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
caryclark@google.com27accef2012-01-25 18:57:23 +00007#include "QuadraticUtilities.h"
caryclark@google.comd88e0892012-03-27 13:23:51 +00008#include <math.h>
caryclark@google.com27accef2012-01-25 18:57:23 +00009
caryclark@google.com03f97062012-08-21 13:13:52 +000010/*
11
12Numeric Solutions (5.6) suggests to solve the quadratic by computing
13
14 Q = -1/2(B + sgn(B)Sqrt(B^2 - 4 A C))
15
16and using the roots
17
18 t1 = Q / A
19 t2 = C / Q
rmistry@google.comd6176b02012-08-23 18:14:13 +000020
caryclark@google.com03f97062012-08-21 13:13:52 +000021*/
22
caryclark@google.com27accef2012-01-25 18:57:23 +000023int quadraticRoots(double A, double B, double C, double t[2]) {
24 B *= 2;
25 double square = B * B - 4 * A * C;
26 if (square < 0) {
27 return 0;
28 }
29 double squareRt = sqrt(square);
30 double Q = (B + (B < 0 ? -squareRt : squareRt)) / -2;
31 int foundRoots = 0;
caryclark@google.com03f97062012-08-21 13:13:52 +000032 double ratio = Q / A;
33 if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
34 if (ratio < FLT_EPSILON) {
35 ratio = 0;
36 } else if (ratio > 1 - FLT_EPSILON) {
37 ratio = 1;
caryclark@google.com78e17132012-04-17 11:40:34 +000038 }
caryclark@google.com03f97062012-08-21 13:13:52 +000039 t[foundRoots++] = ratio;
caryclark@google.com27accef2012-01-25 18:57:23 +000040 }
caryclark@google.com03f97062012-08-21 13:13:52 +000041 ratio = C / Q;
42 if (ratio > -FLT_EPSILON && ratio < 1 + FLT_EPSILON) {
43 if (ratio < FLT_EPSILON) {
44 ratio = 0;
45 } else if (ratio > 1 - FLT_EPSILON) {
46 ratio = 1;
caryclark@google.com78e17132012-04-17 11:40:34 +000047 }
caryclark@google.comc899ad92012-08-23 15:24:42 +000048 if (foundRoots == 0 || fabs(t[0] - ratio) >= FLT_EPSILON) {
49 t[foundRoots++] = ratio;
50 }
caryclark@google.com27accef2012-01-25 18:57:23 +000051 }
52 return foundRoots;
53}
caryclark@google.com8dcf1142012-07-02 20:27:02 +000054
55void dxdy_at_t(const Quadratic& quad, double t, double& x, double& y) {
56 double a = t - 1;
57 double b = 1 - 2 * t;
58 double c = t;
59 if (&x) {
60 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
61 }
62 if (&y) {
63 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
64 }
65}
66
67void xy_at_t(const Quadratic& quad, double t, double& x, double& y) {
68 double one_t = 1 - t;
69 double a = one_t * one_t;
70 double b = 2 * one_t * t;
71 double c = t * t;
72 if (&x) {
73 x = a * quad[0].x + b * quad[1].x + c * quad[2].x;
74 }
75 if (&y) {
76 y = a * quad[0].y + b * quad[1].y + c * quad[2].y;
77 }
78}