blob: 8d14ea5a9e048681adb8fa079f8aa5419a39bd8f [file] [log] [blame]
caryclark@google.coma3f05fa2012-06-01 17:44:28 +00001#include "CurveIntersection.h"
caryclark@google.comfa0588f2012-04-26 21:01:06 +00002#include "Extrema.h"
caryclark@google.comc6825902012-02-03 22:07:47 +00003
caryclark@google.comfa0588f2012-04-26 21:01:06 +00004static int isBoundedByEndPoints(double a, double b, double c, double d)
5{
6 return (a <= b && a <= c && b <= d && c <= d)
7 || (a >= b && a >= c && b >= d && c >= d);
8}
caryclark@google.comc6825902012-02-03 22:07:47 +00009
caryclark@google.comfa0588f2012-04-26 21:01:06 +000010double leftMostT(const Cubic& cubic, double startT, double endT) {
11 double leftTs[2];
12 _Point pt[2];
13 int results = findExtrema(cubic[0].x, cubic[1].x, cubic[2].x, cubic[3].x,
14 leftTs);
15 int best = -1;
16 for (int index = 0; index < results; ++index) {
17 if (startT > leftTs[index] || leftTs[index] > endT) {
18 continue;
19 }
20 if (best < 0) {
21 best = index;
22 continue;
23 }
24 xy_at_t(cubic, leftTs[0], pt[0].x, pt[0].y);
25 xy_at_t(cubic, leftTs[1], pt[1].x, pt[1].y);
26 if (pt[0].x > pt[1].x) {
27 best = 1;
28 }
29 }
30 if (best >= 0) {
31 return leftTs[best];
32 }
33 xy_at_t(cubic, startT, pt[0].x, pt[0].y);
34 xy_at_t(cubic, endT, pt[1].x, pt[1].y);
35 return pt[0].x <= pt[1].x ? startT : endT;
36}
37
38void _Rect::setBounds(const Cubic& cubic) {
39 set(cubic[0]);
40 add(cubic[3]);
41 double tValues[4];
42 int roots = 0;
43 if (!isBoundedByEndPoints(cubic[0].x, cubic[1].x, cubic[2].x, cubic[3].x)) {
44 roots = findExtrema(cubic[0].x, cubic[1].x, cubic[2].x,
45 cubic[3].x, tValues);
46 }
47 if (!isBoundedByEndPoints(cubic[0].y, cubic[1].y, cubic[2].y, cubic[3].y)) {
48 roots += findExtrema(cubic[0].y, cubic[1].y, cubic[2].y,
49 cubic[3].y, &tValues[roots]);
50 }
51 for (int x = 0; x < roots; ++x) {
52 _Point result;
53 xy_at_t(cubic, tValues[x], result.x, result.y);
54 add(result);
55 }
56}
57
58void _Rect::setRawBounds(const Cubic& cubic) {
59 set(cubic[0]);
60 for (int x = 1; x < 4; ++x) {
61 add(cubic[x]);
62 }
63}