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