| 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 |