blob: 6df2d1b16cdbeb8e9bcf484bb7cc275e2f591762 [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");
caryclark@google.coma7e483d2012-08-28 20:44:43 +000025 assert(0);
caryclark@google.com639df892012-01-10 21:46:10 +000026 return false;
27 }
28
29 double distance = endLine.controlPtDistance(q1);
rmistry@google.comd6176b02012-08-23 18:14:13 +000030
caryclark@google.com639df892012-01-10 21:46:10 +000031 // find fat line
32 double top = 0;
33 double bottom = distance / 2; // http://students.cs.byu.edu/~tom/557/text/cic.pdf (7.6)
34 if (top > bottom) {
35 std::swap(top, bottom);
36 }
rmistry@google.comd6176b02012-08-23 18:14:13 +000037
caryclark@google.com639df892012-01-10 21:46:10 +000038 // compute intersecting candidate distance
39 Quadratic distance2y; // points with X of (0, 1/2, 1)
40 endLine.quadDistanceY(q2, distance2y);
rmistry@google.comd6176b02012-08-23 18:14:13 +000041
caryclark@google.com639df892012-01-10 21:46:10 +000042 int flags = 0;
43 if (approximately_lesser(distance2y[0].y, top)) {
44 flags |= kFindTopMin;
45 } else if (approximately_greater(distance2y[0].y, bottom)) {
46 flags |= kFindBottomMin;
47 } else {
48 minT = 0;
49 }
50
51 if (approximately_lesser(distance2y[2].y, top)) {
52 flags |= kFindTopMax;
53 } else if (approximately_greater(distance2y[2].y, bottom)) {
54 flags |= kFindBottomMax;
55 } else {
56 maxT = 1;
57 }
58 // Find the intersection of distance convex hull and fat line.
caryclark@google.com27accef2012-01-25 18:57:23 +000059 int idx = 0;
60 do {
61 int next = idx + 1;
62 if (next == 3) {
63 next = 0;
64 }
65 x_at(distance2y[idx], distance2y[next], top, bottom, flags, minT, maxT);
66 idx = next;
rmistry@google.comd6176b02012-08-23 18:14:13 +000067 } while (idx);
caryclark@google.com639df892012-01-10 21:46:10 +000068 return minT < maxT; // returns false if distance shows no intersection
69}