blob: 2fa9ff686bfa6cac1e66930a7526cbe81333c941 [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.comc6825902012-02-03 22:07:47 +00007#include "CurveIntersection.h"
caryclark@google.com8dcf1142012-07-02 20:27:02 +00008#include "CurveUtilities.h"
caryclark@google.com639df892012-01-10 21:46:10 +00009#include "LineParameters.h"
10#include <algorithm> // used for std::swap
11
12// return false if unable to clip (e.g., unable to create implicit line)
13// caller should subdivide, or create degenerate if the values are too small
14bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double& maxT) {
15 minT = 1;
16 maxT = 0;
17 // determine normalized implicit line equation for pt[0] to pt[3]
18 // of the form ax + by + c = 0, where a*a + b*b == 1
rmistry@google.comd6176b02012-08-23 18:14:13 +000019
caryclark@google.com639df892012-01-10 21:46:10 +000020 // find the implicit line equation parameters
21 LineParameters endLine;
22 endLine.quadEndPoints(q1);
23 if (!endLine.normalize()) {
24 printf("line cannot be normalized: need more code here\n");
25 return false;
26 }
27
28 double distance = endLine.controlPtDistance(q1);
rmistry@google.comd6176b02012-08-23 18:14:13 +000029
caryclark@google.com639df892012-01-10 21:46:10 +000030 // find fat line
31 double top = 0;
32 double bottom = distance / 2; // http://students.cs.byu.edu/~tom/557/text/cic.pdf (7.6)
33 if (top > bottom) {
34 std::swap(top, bottom);
35 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000036
caryclark@google.com639df892012-01-10 21:46:10 +000037 // compute intersecting candidate distance
38 Quadratic distance2y; // points with X of (0, 1/2, 1)
39 endLine.quadDistanceY(q2, distance2y);
rmistry@google.comd6176b02012-08-23 18:14:13 +000040
caryclark@google.com639df892012-01-10 21:46:10 +000041 int flags = 0;
42 if (approximately_lesser(distance2y[0].y, top)) {
43 flags |= kFindTopMin;
44 } else if (approximately_greater(distance2y[0].y, bottom)) {
45 flags |= kFindBottomMin;
46 } else {
47 minT = 0;
48 }
49
50 if (approximately_lesser(distance2y[2].y, top)) {
51 flags |= kFindTopMax;
52 } else if (approximately_greater(distance2y[2].y, bottom)) {
53 flags |= kFindBottomMax;
54 } else {
55 maxT = 1;
56 }
57 // Find the intersection of distance convex hull and fat line.
caryclark@google.com27accef2012-01-25 18:57:23 +000058 int idx = 0;
59 do {
60 int next = idx + 1;
61 if (next == 3) {
62 next = 0;
63 }
64 x_at(distance2y[idx], distance2y[next], top, bottom, flags, minT, maxT);
65 idx = next;
rmistry@google.comd6176b02012-08-23 18:14:13 +000066 } while (idx);
caryclark@google.com639df892012-01-10 21:46:10 +000067 return minT < maxT; // returns false if distance shows no intersection
68}