caryclark@google.com | c682590 | 2012-02-03 22:07:47 +0000 | [diff] [blame] | 1 | #include "CurveIntersection.h" |
caryclark@google.com | 8dcf114 | 2012-07-02 20:27:02 +0000 | [diff] [blame] | 2 | #include "CurveUtilities.h" |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 3 | #include "LineParameters.h" |
| 4 | #include <algorithm> // used for std::swap |
| 5 | |
| 6 | // return false if unable to clip (e.g., unable to create implicit line) |
| 7 | // caller should subdivide, or create degenerate if the values are too small |
| 8 | bool bezier_clip(const Cubic& cubic1, const Cubic& cubic2, double& minT, double& maxT) { |
| 9 | minT = 1; |
| 10 | maxT = 0; |
| 11 | // determine normalized implicit line equation for pt[0] to pt[3] |
| 12 | // of the form ax + by + c = 0, where a*a + b*b == 1 |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame^] | 13 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 14 | // find the implicit line equation parameters |
| 15 | LineParameters endLine; |
| 16 | endLine.cubicEndPoints(cubic1); |
| 17 | if (!endLine.normalize()) { |
| 18 | printf("line cannot be normalized: need more code here\n"); |
| 19 | return false; |
| 20 | } |
| 21 | |
| 22 | double distance[2]; |
| 23 | endLine.controlPtDistance(cubic1, distance); |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame^] | 24 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 25 | // find fat line |
| 26 | double top = distance[0]; |
| 27 | double bottom = distance[1]; |
| 28 | if (top > bottom) { |
| 29 | std::swap(top, bottom); |
| 30 | } |
| 31 | if (top * bottom >= 0) { |
| 32 | const double scale = 3/4.0; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf (13) |
| 33 | if (top < 0) { |
| 34 | top *= scale; |
| 35 | bottom = 0; |
| 36 | } else { |
| 37 | top = 0; |
| 38 | bottom *= scale; |
| 39 | } |
| 40 | } else { |
| 41 | const double scale = 4/9.0; // http://cagd.cs.byu.edu/~tom/papers/bezclip.pdf (15) |
| 42 | top *= scale; |
| 43 | bottom *= scale; |
| 44 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame^] | 45 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 46 | // compute intersecting candidate distance |
| 47 | Cubic distance2y; // points with X of (0, 1/3, 2/3, 1) |
| 48 | endLine.cubicDistanceY(cubic2, distance2y); |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame^] | 49 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 50 | int flags = 0; |
| 51 | if (approximately_lesser(distance2y[0].y, top)) { |
| 52 | flags |= kFindTopMin; |
| 53 | } else if (approximately_greater(distance2y[0].y, bottom)) { |
| 54 | flags |= kFindBottomMin; |
| 55 | } else { |
| 56 | minT = 0; |
| 57 | } |
| 58 | |
| 59 | if (approximately_lesser(distance2y[3].y, top)) { |
| 60 | flags |= kFindTopMax; |
| 61 | } else if (approximately_greater(distance2y[3].y, bottom)) { |
| 62 | flags |= kFindBottomMax; |
| 63 | } else { |
| 64 | maxT = 1; |
| 65 | } |
| 66 | // Find the intersection of distance convex hull and fat line. |
| 67 | char to_0[2]; |
| 68 | char to_3[2]; |
| 69 | bool do_1_2_edge = convex_x_hull(distance2y, to_0, to_3); |
| 70 | x_at(distance2y[0], distance2y[to_0[0]], top, bottom, flags, minT, maxT); |
| 71 | if (to_0[0] != to_0[1]) { |
| 72 | x_at(distance2y[0], distance2y[to_0[1]], top, bottom, flags, minT, maxT); |
| 73 | } |
| 74 | x_at(distance2y[to_3[0]], distance2y[3], top, bottom, flags, minT, maxT); |
| 75 | if (to_3[0] != to_3[1]) { |
| 76 | x_at(distance2y[to_3[1]], distance2y[3], top, bottom, flags, minT, maxT); |
| 77 | } |
| 78 | if (do_1_2_edge) { |
| 79 | x_at(distance2y[1], distance2y[2], top, bottom, flags, minT, maxT); |
| 80 | } |
rmistry@google.com | d6176b0 | 2012-08-23 18:14:13 +0000 | [diff] [blame^] | 81 | |
caryclark@google.com | 639df89 | 2012-01-10 21:46:10 +0000 | [diff] [blame] | 82 | return minT < maxT; // returns false if distance shows no intersection |
| 83 | } |
| 84 | |