OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 #include "SkIntersections.h" | 7 #include "SkIntersections.h" |
8 #include "SkPathOpsCubic.h" | 8 #include "SkPathOpsCubic.h" |
9 #include "SkPathOpsLine.h" | 9 #include "SkPathOpsLine.h" |
10 | 10 |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 98 |
99 int intersect() { | 99 int intersect() { |
100 addEndPoints(); | 100 addEndPoints(); |
101 double rootVals[3]; | 101 double rootVals[3]; |
102 int roots = intersectRay(rootVals); | 102 int roots = intersectRay(rootVals); |
103 for (int index = 0; index < roots; ++index) { | 103 for (int index = 0; index < roots; ++index) { |
104 double cubicT = rootVals[index]; | 104 double cubicT = rootVals[index]; |
105 double lineT = findLineT(cubicT); | 105 double lineT = findLineT(cubicT); |
106 if (pinTs(&cubicT, &lineT)) { | 106 if (pinTs(&cubicT, &lineT)) { |
107 SkDPoint pt = line.xyAtT(lineT); | 107 SkDPoint pt = line.xyAtT(lineT); |
| 108 #if ONE_OFF_DEBUG |
| 109 SkDPoint cPt = cubic.xyAtT(cubicT); |
| 110 SkDebugf("%s pt=(%1.9g,%1.9g) cPt=(%1.9g,%1.9g)\n", __FUNCTION__, pt
.fX, pt.fY, |
| 111 cPt.fX, cPt.fY); |
| 112 #endif |
108 intersections.insert(cubicT, lineT, pt); | 113 intersections.insert(cubicT, lineT, pt); |
109 } | 114 } |
110 } | 115 } |
111 return intersections.used(); | 116 return intersections.used(); |
112 } | 117 } |
113 | 118 |
114 int horizontalIntersect(double axisIntercept, double roots[3]) { | 119 int horizontalIntersect(double axisIntercept, double roots[3]) { |
115 double A, B, C, D; | 120 double A, B, C, D; |
116 SkDCubic::Coefficients(&cubic[0].fY, &A, &B, &C, &D); | 121 SkDCubic::Coefficients(&cubic[0].fY, &A, &B, &C, &D); |
117 D -= axisIntercept; | 122 D -= axisIntercept; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 if (flipped) { | 163 if (flipped) { |
159 intersections.flip(); | 164 intersections.flip(); |
160 } | 165 } |
161 return intersections.used(); | 166 return intersections.used(); |
162 } | 167 } |
163 | 168 |
164 protected: | 169 protected: |
165 | 170 |
166 void addEndPoints() { | 171 void addEndPoints() { |
167 for (int cIndex = 0; cIndex < 4; cIndex += 3) { | 172 for (int cIndex = 0; cIndex < 4; cIndex += 3) { |
| 173 bool foundEnd = false; |
168 for (int lIndex = 0; lIndex < 2; lIndex++) { | 174 for (int lIndex = 0; lIndex < 2; lIndex++) { |
169 if (cubic[cIndex] == line[lIndex]) { | 175 if (cubic[cIndex] == line[lIndex]) { |
170 intersections.insert(cIndex >> 1, lIndex, line[lIndex]); | 176 intersections.insert(cIndex >> 1, lIndex, line[lIndex]); |
| 177 foundEnd = true; |
171 } | 178 } |
172 } | 179 } |
| 180 // for the test case this was written for, the dist / error ratio was 17
0.6667 |
| 181 // it looks like the cubic stops short of touching the line, but this fi
xed it. |
| 182 if (foundEnd) { |
| 183 continue; |
| 184 } |
| 185 // See if the cubic end touches the line. |
| 186 double dist = line.isLeft(cubic[cIndex]); // this distance isn't cartesi
an |
| 187 SkDVector lineLen = line[1] - line[0]; // the x/y magnitudes of the line |
| 188 // compute the ULPS of the larger of the x/y deltas |
| 189 double larger = SkTMax(SkTAbs(lineLen.fX), SkTAbs(lineLen.fY)); |
| 190 if (!RoughlyEqualUlps(larger, larger + dist)) { // is the dist within UL
PS tolerance? |
| 191 continue; |
| 192 } |
| 193 double lineT = findLineT(cIndex >> 1); |
| 194 if (!between(0, lineT, 1)) { |
| 195 continue; |
| 196 } |
| 197 SkDPoint linePt = line.xyAtT(lineT); |
| 198 if (linePt.approximatelyEqual(cubic[cIndex])) { |
| 199 intersections.insert(cIndex >> 1, lineT, cubic[cIndex]); |
| 200 } |
173 } | 201 } |
174 } | 202 } |
175 | 203 |
176 void addHorizontalEndPoints(double left, double right, double y) { | 204 void addHorizontalEndPoints(double left, double right, double y) { |
177 for (int cIndex = 0; cIndex < 4; cIndex += 3) { | 205 for (int cIndex = 0; cIndex < 4; cIndex += 3) { |
178 if (cubic[cIndex].fY != y) { | 206 if (cubic[cIndex].fY != y) { |
179 continue; | 207 continue; |
180 } | 208 } |
181 if (cubic[cIndex].fX == left) { | 209 if (cubic[cIndex].fX == left) { |
182 intersections.insert(cIndex >> 1, 0, cubic[cIndex]); | 210 intersections.insert(cIndex >> 1, 0, cubic[cIndex]); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
256 } | 284 } |
257 | 285 |
258 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { | 286 int SkIntersections::intersectRay(const SkDCubic& cubic, const SkDLine& line) { |
259 LineCubicIntersections c(cubic, line, *this); | 287 LineCubicIntersections c(cubic, line, *this); |
260 fUsed = c.intersectRay(fT[0]); | 288 fUsed = c.intersectRay(fT[0]); |
261 for (int index = 0; index < fUsed; ++index) { | 289 for (int index = 0; index < fUsed; ++index) { |
262 fPt[index] = cubic.xyAtT(fT[0][index]); | 290 fPt[index] = cubic.xyAtT(fT[0][index]); |
263 } | 291 } |
264 return fUsed; | 292 return fUsed; |
265 } | 293 } |
OLD | NEW |