blob: c41e0d7cdcf3b85b8d660022e25eb9026b77f0b3 [file] [log] [blame]
caryclark@google.com639df892012-01-10 21:46:10 +00001#include "CubicIntersection.h"
2#include "Intersections.h"
3#include "LineIntersection.h"
4
5static bool chop(const Cubic& smaller, const Cubic& larger,
6 Intersections& intersections, double minT, double maxT);
7
8static bool intersect(const Cubic& smaller, const Cubic& larger,
9 Intersections& intersections) {
10 // FIXME: carry order with cubic so we don't call it repeatedly
11 Cubic smallResult;
12 if (reduceOrder(smaller, smallResult, kReduceOrder_NoQuadraticsAllowed) <= 2) {
13 Cubic largeResult;
14 if (reduceOrder(larger, largeResult, kReduceOrder_NoQuadraticsAllowed) <= 2) {
15 _Point pt;
16 const _Line& smallLine = (const _Line&) smallResult;
17 const _Line& largeLine = (const _Line&) largeResult;
18 if (!lineIntersect(smallLine, largeLine, &pt)) {
19 return false;
20 }
21 double smallT = t_at(smallLine, pt);
22 double largeT = t_at(largeLine, pt);
23 intersections.add(smallT, largeT);
24 return true;
25 }
26 }
27 double minT, maxT;
28 if (!bezier_clip(smaller, larger, minT, maxT)) {
29 if (minT == maxT) {
30 intersections.add(minT, 0.5);
31 return true;
32 }
33 return false;
34 }
35 return chop(larger, smaller, intersections, minT, maxT);
36}
37
38bool chop(const Cubic& smaller, const Cubic& larger,
39 Intersections& intersections, double minT, double maxT) {
40 intersections.swap();
41 if (maxT - minT > 0.8) { // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf Multiple intersections
42 CubicPair cubicPair;
43 chop_at(larger, cubicPair, 0.5);
44 int used = intersections.used();
45 if (intersect(cubicPair.first(), smaller, intersections)) {
46 intersections.offset(used, 0, 0.5);
47 }
48 used = intersections.used();
49 if (intersect(cubicPair.second(), smaller, intersections)) {
50 intersections.offset(used, 0.5, 1);
51 }
52 intersections.swap();
53 return intersections.intersected();
54 }
55 Cubic cut;
56 sub_divide(smaller, minT, maxT, cut);
57 int used = intersections.used();
58 bool result = intersect(cut, larger, intersections);
59 if (result) {
60 intersections.offset(used, minT, maxT);
61 }
62 intersections.swap();
63 return result;
64}
65
66bool intersectStart(const Cubic& cubic1, const Cubic& cubic2,
67 Intersections& intersections) {
68 double minT1, minT2, maxT1, maxT2;
69 if (!bezier_clip(cubic2, cubic1, minT1, maxT1)) {
70 return false;
71 }
72 if (!bezier_clip(cubic1, cubic2, minT2, maxT2)) {
73 return false;
74 }
75 if (maxT1 - minT1 < maxT2 - minT2) {
76 intersections.swap();
77 return chop(cubic1, cubic2, intersections, minT1, maxT1);
78 }
79 return chop(cubic2, cubic1, intersections, minT2, maxT2);
80}