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 "SkPathOpsLine.h" | 8 #include "SkPathOpsLine.h" |
9 | 9 |
10 /* Determine the intersection point of two lines. This assumes the lines are not
parallel, | 10 /* Determine the intersection point of two lines. This assumes the lines are not
parallel, |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 double ab0x = a[0].fX - b[0].fX; | 147 double ab0x = a[0].fX - b[0].fX; |
148 double numerA = ab0y * bxLen - byLen * ab0x; | 148 double numerA = ab0y * bxLen - byLen * ab0x; |
149 double numerB = ab0y * axLen - ayLen * ab0x; | 149 double numerB = ab0y * axLen - ayLen * ab0x; |
150 double denom = axByLen - ayBxLen; | 150 double denom = axByLen - ayBxLen; |
151 if (between(0, numerA, denom) && between(0, numerB, denom)) { | 151 if (between(0, numerA, denom) && between(0, numerB, denom)) { |
152 fT[0][0] = numerA / denom; | 152 fT[0][0] = numerA / denom; |
153 fT[1][0] = numerB / denom; | 153 fT[1][0] = numerB / denom; |
154 computePoints(a, 1); | 154 computePoints(a, 1); |
155 } | 155 } |
156 } | 156 } |
| 157 /* Allow tracking that both sets of end points are near each other -- the lines
are entirely |
| 158 coincident -- even when the end points are not exactly the same. |
| 159 Mark this as a 'wild card' for the end points, so that either point is consid
ered totally |
| 160 coincident. Then, avoid folding the lines over each other, but allow either e
nd to mate |
| 161 to the next set of lines. |
| 162 */ |
157 if (fAllowNear || !unparallel) { | 163 if (fAllowNear || !unparallel) { |
158 for (int iA = 0; iA < 2; ++iA) { | 164 double aNearB[2]; |
159 if ((t = b.nearPoint(a[iA])) >= 0) { | 165 double bNearA[2]; |
160 insert(iA, t, a[iA]); | 166 bool aNotB[2] = {false, false}; |
| 167 bool bNotA[2] = {false, false}; |
| 168 int nearCount = 0; |
| 169 for (int index = 0; index < 2; ++index) { |
| 170 aNearB[index] = t = b.nearPoint(a[index], &aNotB[index]); |
| 171 nearCount += t >= 0; |
| 172 bNearA[index] = t = a.nearPoint(b[index], &bNotA[index]); |
| 173 nearCount += t >= 0; |
| 174 } |
| 175 if (nearCount > 0) { |
| 176 for (int iA = 0; iA < 2; ++iA) { |
| 177 if (!aNotB[iA]) { |
| 178 continue; |
| 179 } |
| 180 int nearer = aNearB[iA] > 0.5; |
| 181 if (!bNotA[nearer]) { |
| 182 continue; |
| 183 } |
| 184 SkASSERT(a[iA] != b[nearer]); |
| 185 SkASSERT(iA == (bNearA[nearer] > 0.5)); |
| 186 fNearlySame[iA] = true; |
| 187 insertNear(iA, nearer, a[iA], b[nearer]); |
| 188 aNearB[iA] = -1; |
| 189 bNearA[nearer] = -1; |
| 190 nearCount -= 2; |
161 } | 191 } |
162 } | 192 if (nearCount > 0) { |
163 for (int iB = 0; iB < 2; ++iB) { | 193 for (int iA = 0; iA < 2; ++iA) { |
164 if ((t = a.nearPoint(b[iB])) >= 0) { | 194 if (aNearB[iA] >= 0) { |
165 insert(t, iB, b[iB]); | 195 insert(iA, aNearB[iA], a[iA]); |
| 196 } |
| 197 } |
| 198 for (int iB = 0; iB < 2; ++iB) { |
| 199 if (bNearA[iB] >= 0) { |
| 200 insert(bNearA[iB], iB, b[iB]); |
| 201 } |
| 202 } |
166 } | 203 } |
167 } | 204 } |
168 } | 205 } |
169 cleanUpParallelLines(!unparallel); | 206 cleanUpParallelLines(!unparallel); |
170 SkASSERT(fUsed <= 2); | 207 SkASSERT(fUsed <= 2); |
171 return fUsed; | 208 return fUsed; |
172 } | 209 } |
173 | 210 |
174 static int horizontal_coincident(const SkDLine& line, double y) { | 211 static int horizontal_coincident(const SkDLine& line, double y) { |
175 double min = line[0].fY; | 212 double min = line[0].fY; |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 for (int index = 0; index < result; ++index) { | 270 for (int index = 0; index < result; ++index) { |
234 fT[1][index] = 1 - fT[1][index]; | 271 fT[1][index] = 1 - fT[1][index]; |
235 } | 272 } |
236 } | 273 } |
237 fPt[0].fX = xIntercept; | 274 fPt[0].fX = xIntercept; |
238 fPt[0].fY = y; | 275 fPt[0].fY = y; |
239 fUsed = 1; | 276 fUsed = 1; |
240 } | 277 } |
241 } | 278 } |
242 if (fAllowNear || result == 2) { | 279 if (fAllowNear || result == 2) { |
243 if ((t = line.nearPoint(leftPt)) >= 0) { | 280 if ((t = line.nearPoint(leftPt, NULL)) >= 0) { |
244 insert(t, (double) flipped, leftPt); | 281 insert(t, (double) flipped, leftPt); |
245 } | 282 } |
246 if (left != right) { | 283 if (left != right) { |
247 const SkDPoint rightPt = { right, y }; | 284 const SkDPoint rightPt = { right, y }; |
248 if ((t = line.nearPoint(rightPt)) >= 0) { | 285 if ((t = line.nearPoint(rightPt, NULL)) >= 0) { |
249 insert(t, (double) !flipped, rightPt); | 286 insert(t, (double) !flipped, rightPt); |
250 } | 287 } |
251 for (int index = 0; index < 2; ++index) { | 288 for (int index = 0; index < 2; ++index) { |
252 if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0)
{ | 289 if ((t = SkDLine::NearPointH(line[index], left, right, y)) >= 0)
{ |
253 insert((double) index, flipped ? 1 - t : t, line[index]); | 290 insert((double) index, flipped ? 1 - t : t, line[index]); |
254 } | 291 } |
255 } | 292 } |
256 } | 293 } |
257 } | 294 } |
258 cleanUpParallelLines(result == 2); | 295 cleanUpParallelLines(result == 2); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 for (int index = 0; index < result; ++index) { | 358 for (int index = 0; index < result; ++index) { |
322 fT[1][index] = 1 - fT[1][index]; | 359 fT[1][index] = 1 - fT[1][index]; |
323 } | 360 } |
324 } | 361 } |
325 fPt[0].fX = x; | 362 fPt[0].fX = x; |
326 fPt[0].fY = yIntercept; | 363 fPt[0].fY = yIntercept; |
327 fUsed = 1; | 364 fUsed = 1; |
328 } | 365 } |
329 } | 366 } |
330 if (fAllowNear || result == 2) { | 367 if (fAllowNear || result == 2) { |
331 if ((t = line.nearPoint(topPt)) >= 0) { | 368 if ((t = line.nearPoint(topPt, NULL)) >= 0) { |
332 insert(t, (double) flipped, topPt); | 369 insert(t, (double) flipped, topPt); |
333 } | 370 } |
334 if (top != bottom) { | 371 if (top != bottom) { |
335 SkDPoint bottomPt = { x, bottom }; | 372 SkDPoint bottomPt = { x, bottom }; |
336 if ((t = line.nearPoint(bottomPt)) >= 0) { | 373 if ((t = line.nearPoint(bottomPt, NULL)) >= 0) { |
337 insert(t, (double) !flipped, bottomPt); | 374 insert(t, (double) !flipped, bottomPt); |
338 } | 375 } |
339 for (int index = 0; index < 2; ++index) { | 376 for (int index = 0; index < 2; ++index) { |
340 if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0)
{ | 377 if ((t = SkDLine::NearPointV(line[index], top, bottom, x)) >= 0)
{ |
341 insert((double) index, flipped ? 1 - t : t, line[index]); | 378 insert((double) index, flipped ? 1 - t : t, line[index]); |
342 } | 379 } |
343 } | 380 } |
344 } | 381 } |
345 } | 382 } |
346 cleanUpParallelLines(result == 2); | 383 cleanUpParallelLines(result == 2); |
347 SkASSERT(fUsed <= 2); | 384 SkASSERT(fUsed <= 2); |
348 return fUsed; | 385 return fUsed; |
349 } | 386 } |
350 | 387 |
351 // from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.p
y | 388 // from http://www.bryceboe.com/wordpress/wp-content/uploads/2006/10/intersect.p
y |
352 // 4 subs, 2 muls, 1 cmp | 389 // 4 subs, 2 muls, 1 cmp |
353 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) { | 390 static bool ccw(const SkDPoint& A, const SkDPoint& B, const SkDPoint& C) { |
354 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX); | 391 return (C.fY - A.fY) * (B.fX - A.fX) > (B.fY - A.fY) * (C.fX - A.fX); |
355 } | 392 } |
356 | 393 |
357 // 16 subs, 8 muls, 6 cmps | 394 // 16 subs, 8 muls, 6 cmps |
358 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) { | 395 bool SkIntersections::Test(const SkDLine& a, const SkDLine& b) { |
359 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1]) | 396 return ccw(a[0], b[0], b[1]) != ccw(a[1], b[0], b[1]) |
360 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]); | 397 && ccw(a[0], a[1], b[0]) != ccw(a[0], a[1], b[1]); |
361 } | 398 } |
OLD | NEW |