blob: d9d984d5ddf7827282a7962ea1d1203c8e5b543f [file] [log] [blame]
caryclark@google.comc6825902012-02-03 22:07:47 +00001#include "CurveIntersection.h"
caryclark@google.com639df892012-01-10 21:46:10 +00002#include "LineParameters.h"
3#include <algorithm> // used for std::swap
4
5// return false if unable to clip (e.g., unable to create implicit line)
6// caller should subdivide, or create degenerate if the values are too small
7bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double& maxT) {
8 minT = 1;
9 maxT = 0;
10 // determine normalized implicit line equation for pt[0] to pt[3]
11 // of the form ax + by + c = 0, where a*a + b*b == 1
12
13 // find the implicit line equation parameters
14 LineParameters endLine;
15 endLine.quadEndPoints(q1);
16 if (!endLine.normalize()) {
17 printf("line cannot be normalized: need more code here\n");
18 return false;
19 }
20
21 double distance = endLine.controlPtDistance(q1);
22
23 // find fat line
24 double top = 0;
25 double bottom = distance / 2; // http://students.cs.byu.edu/~tom/557/text/cic.pdf (7.6)
26 if (top > bottom) {
27 std::swap(top, bottom);
28 }
29
30 // compute intersecting candidate distance
31 Quadratic distance2y; // points with X of (0, 1/2, 1)
32 endLine.quadDistanceY(q2, distance2y);
33
34 int flags = 0;
35 if (approximately_lesser(distance2y[0].y, top)) {
36 flags |= kFindTopMin;
37 } else if (approximately_greater(distance2y[0].y, bottom)) {
38 flags |= kFindBottomMin;
39 } else {
40 minT = 0;
41 }
42
43 if (approximately_lesser(distance2y[2].y, top)) {
44 flags |= kFindTopMax;
45 } else if (approximately_greater(distance2y[2].y, bottom)) {
46 flags |= kFindBottomMax;
47 } else {
48 maxT = 1;
49 }
50 // Find the intersection of distance convex hull and fat line.
caryclark@google.com27accef2012-01-25 18:57:23 +000051 int idx = 0;
52 do {
53 int next = idx + 1;
54 if (next == 3) {
55 next = 0;
56 }
57 x_at(distance2y[idx], distance2y[next], top, bottom, flags, minT, maxT);
58 idx = next;
59 } while (idx);
caryclark@google.com639df892012-01-10 21:46:10 +000060 return minT < maxT; // returns false if distance shows no intersection
61}