| OLD | NEW |
| (Empty) |
| 1 /* | |
| 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 */ | |
| 7 #include "CurveIntersection.h" | |
| 8 #include "CurveUtilities.h" | |
| 9 #include "LineParameters.h" | |
| 10 | |
| 11 #define DEBUG_BEZIER_CLIP 1 | |
| 12 | |
| 13 // return false if unable to clip (e.g., unable to create implicit line) | |
| 14 // caller should subdivide, or create degenerate if the values are too small | |
| 15 bool bezier_clip(const Quadratic& q1, const Quadratic& q2, double& minT, double&
maxT) { | |
| 16 minT = 1; | |
| 17 maxT = 0; | |
| 18 // determine normalized implicit line equation for pt[0] to pt[3] | |
| 19 // of the form ax + by + c = 0, where a*a + b*b == 1 | |
| 20 | |
| 21 // find the implicit line equation parameters | |
| 22 LineParameters endLine; | |
| 23 endLine.quadEndPoints(q1); | |
| 24 if (!endLine.normalize()) { | |
| 25 printf("line cannot be normalized: need more code here\n"); | |
| 26 SkASSERT(0); | |
| 27 return false; | |
| 28 } | |
| 29 | |
| 30 double distance = endLine.controlPtDistance(q1); | |
| 31 | |
| 32 // find fat line | |
| 33 double top = 0; | |
| 34 double bottom = distance / 2; // http://students.cs.byu.edu/~tom/557/text/ci
c.pdf (7.6) | |
| 35 if (top > bottom) { | |
| 36 SkTSwap(top, bottom); | |
| 37 } | |
| 38 | |
| 39 // compute intersecting candidate distance | |
| 40 Quadratic distance2y; // points with X of (0, 1/2, 1) | |
| 41 endLine.quadDistanceY(q2, distance2y); | |
| 42 | |
| 43 int flags = 0; | |
| 44 if (approximately_lesser_or_equal(distance2y[0].y, top)) { | |
| 45 flags |= kFindTopMin; | |
| 46 } else if (approximately_greater_or_equal(distance2y[0].y, bottom)) { | |
| 47 flags |= kFindBottomMin; | |
| 48 } else { | |
| 49 minT = 0; | |
| 50 } | |
| 51 | |
| 52 if (approximately_lesser_or_equal(distance2y[2].y, top)) { | |
| 53 flags |= kFindTopMax; | |
| 54 } else if (approximately_greater_or_equal(distance2y[2].y, bottom)) { | |
| 55 flags |= kFindBottomMax; | |
| 56 } else { | |
| 57 maxT = 1; | |
| 58 } | |
| 59 // Find the intersection of distance convex hull and fat line. | |
| 60 int idx = 0; | |
| 61 do { | |
| 62 int next = idx + 1; | |
| 63 if (next == 3) { | |
| 64 next = 0; | |
| 65 } | |
| 66 x_at(distance2y[idx], distance2y[next], top, bottom, flags, minT, maxT); | |
| 67 idx = next; | |
| 68 } while (idx); | |
| 69 #if DEBUG_BEZIER_CLIP | |
| 70 _Rect r1, r2; | |
| 71 r1.setBounds(q1); | |
| 72 r2.setBounds(q2); | |
| 73 _Point testPt = {0.487, 0.337}; | |
| 74 if (r1.contains(testPt) && r2.contains(testPt)) { | |
| 75 printf("%s q1=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g)" | |
| 76 " q2=(%1.9g,%1.9g %1.9g,%1.9g %1.9g,%1.9g) minT=%1.9g maxT=%1.9g
\n", | |
| 77 __FUNCTION__, q1[0].x, q1[0].y, q1[1].x, q1[1].y, q1[2].x, q1[2]
.y, | |
| 78 q2[0].x, q2[0].y, q2[1].x, q2[1].y, q2[2].x, q2[2].y, minT, maxT
); | |
| 79 } | |
| 80 #endif | |
| 81 return minT < maxT; // returns false if distance shows no intersection | |
| 82 } | |
| OLD | NEW |