Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(72)

Side by Side Diff: src/pathops/SkDCubicIntersection.cpp

Issue 19543005: turn off debugging printfs (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: remove unused code Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/pathops/SkDCubicLineIntersection.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 7
8 #include "SkIntersections.h" 8 #include "SkIntersections.h"
9 #include "SkPathOpsCubic.h" 9 #include "SkPathOpsCubic.h"
10 #include "SkPathOpsLine.h" 10 #include "SkPathOpsLine.h"
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 && tLimits1[1][0] >= t2Start && tLimits1[1][1] <= t2) { 107 && tLimits1[1][0] >= t2Start && tLimits1[1][1] <= t2) {
108 SkDebugf("%.*s %s t1=(%1.9g,%1.9g) t2=(%1.9g,%1.9g)", i.depth()* 2, tab, 108 SkDebugf("%.*s %s t1=(%1.9g,%1.9g) t2=(%1.9g,%1.9g)", i.depth()* 2, tab,
109 __FUNCTION__, t1Start, t1, t2Start, t2); 109 __FUNCTION__, t1Start, t1, t2Start, t2);
110 SkIntersections xlocals; 110 SkIntersections xlocals;
111 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, xlocals); 111 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, xlocals);
112 SkDebugf(" xlocals.fUsed=%d\n", xlocals.used()); 112 SkDebugf(" xlocals.fUsed=%d\n", xlocals.used());
113 } 113 }
114 #endif 114 #endif
115 SkIntersections locals; 115 SkIntersections locals;
116 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals); 116 intersectWithOrder(s1.fQuad, o1, s2.fQuad, o2, locals);
117 double coStart[2] = { -1 };
118 SkDPoint coPoint;
119 int tCount = locals.used(); 117 int tCount = locals.used();
120 for (int tIdx = 0; tIdx < tCount; ++tIdx) { 118 for (int tIdx = 0; tIdx < tCount; ++tIdx) {
121 double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx]; 119 double to1 = t1Start + (t1 - t1Start) * locals[0][tIdx];
122 double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx]; 120 double to2 = t2Start + (t2 - t2Start) * locals[1][tIdx];
123 // if the computed t is not sufficiently precise, iterate 121 // if the computed t is not sufficiently precise, iterate
124 SkDPoint p1 = cubic1.xyAtT(to1); 122 SkDPoint p1 = cubic1.ptAtT(to1);
125 SkDPoint p2 = cubic2.xyAtT(to2); 123 SkDPoint p2 = cubic2.ptAtT(to2);
126 if (p1.approximatelyEqual(p2)) { 124 if (p1.approximatelyEqual(p2)) {
127 if (locals.isCoincident(tIdx)) { 125 SkASSERT(!locals.isCoincident(tIdx));
128 if (coStart[0] < 0) { 126 if (&cubic1 != &cubic2 || !approximately_equal(to1, to2)) {
129 coStart[0] = to1;
130 coStart[1] = to2;
131 coPoint = p1;
132 } else {
133 i.insertCoincidentPair(coStart[0], to1, coStart[1], to2, coPoint, p1);
134 coStart[0] = -1;
135 }
136 } else if (&cubic1 != &cubic2 || !approximately_equal(to1, t o2)) {
137 if (i.swapped()) { // FIXME: insert should respect swa p 127 if (i.swapped()) { // FIXME: insert should respect swa p
138 i.insert(to2, to1, p1); 128 i.insert(to2, to1, p1);
139 } else { 129 } else {
140 i.insert(to1, to2, p1); 130 i.insert(to1, to2, p1);
141 } 131 }
142 } 132 }
143 } else { 133 } else {
144 double offset = precisionScale / 16; // FIME: const is arbi trary: test, refine 134 double offset = precisionScale / 16; // FIME: const is arbi trary: test, refine
145 double c1Bottom = tIdx == 0 ? 0 : 135 double c1Bottom = tIdx == 0 ? 0 :
146 (t1Start + (t1 - t1Start) * locals[0][tIdx - 1] + to 1) / 2; 136 (t1Start + (t1 - t1Start) * locals[0][tIdx - 1] + to 1) / 2;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
243 i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1); 233 i.used(), i.used() > 0 ? i[0][i.used() - 1] : -1);
244 #endif 234 #endif
245 } 235 }
246 // intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offs et, i); 236 // intersect(cubic1, c1Min, c1Max, cubic2, c2Min, c2Max, offs et, i);
247 // FIXME: if no intersection is found, either quadratics int ersected where 237 // FIXME: if no intersection is found, either quadratics int ersected where
248 // cubics did not, or the intersection was missed. In the fo rmer case, expect 238 // cubics did not, or the intersection was missed. In the fo rmer case, expect
249 // the quadratics to be nearly parallel at the point of inte rsection, and check 239 // the quadratics to be nearly parallel at the point of inte rsection, and check
250 // for that. 240 // for that.
251 } 241 }
252 } 242 }
253 SkASSERT(coStart[0] == -1);
254 t2Start = t2; 243 t2Start = t2;
255 } 244 }
256 t1Start = t1; 245 t1Start = t1;
257 } 246 }
258 i.downDepth(); 247 i.downDepth();
259 } 248 }
260 249
261 #define LINE_FRACTION 0.1 250 #define LINE_FRACTION 0.1
262 251
263 // intersect the end of the cubic with the other. Try lines from the end to cont rol and opposite 252 // intersect the end of the cubic with the other. Try lines from the end to cont rol and opposite
264 // end to determine range of t on opposite cubic. 253 // end to determine range of t on opposite cubic.
265 static void intersectEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cub ic2, 254 static void intersectEnd(const SkDCubic& cubic1, bool start, const SkDCubic& cub ic2,
266 const SkDRect& bounds2, SkIntersections& i) { 255 const SkDRect& bounds2, bool selfIntersect, SkIntersect ions& i) {
267 SkDLine line; 256 SkDLine line;
268 int t1Index = start ? 0 : 3; 257 int t1Index = start ? 0 : 3;
258 bool swap = i.swapped();
259 double testT = (double) !start;
260 // quad/quad at this point checks to see if exact matches have already been found
261 // cubic/cubic can't reject so easily since cubics can intersect same point more than once
262 if (!selfIntersect) {
263 SkDLine tmpLine;
264 tmpLine[0] = tmpLine[1] = cubic2[t1Index];
265 tmpLine[1].fX += cubic2[2 - start].fY - cubic2[t1Index].fY;
266 tmpLine[1].fY -= cubic2[2 - start].fX - cubic2[t1Index].fX;
267 SkIntersections impTs;
268 impTs.intersectRay(cubic1, tmpLine);
269 for (int index = 0; index < impTs.used(); ++index) {
270 SkDPoint realPt = impTs.pt(index);
271 if (!tmpLine[0].approximatelyEqualHalf(realPt)) {
272 continue;
273 }
274 if (swap) {
275 i.insert(testT, impTs[0][index], tmpLine[0]);
276 } else {
277 i.insert(impTs[0][index], testT, tmpLine[0]);
278 }
279 return;
280 }
281 }
269 // don't bother if the two cubics are connnected 282 // don't bother if the two cubics are connnected
270 #if 1
271 static const int kPointsInCubic = 4; // FIXME: move to DCubic, replace '4' w ith this 283 static const int kPointsInCubic = 4; // FIXME: move to DCubic, replace '4' w ith this
272 static const int kMaxLineCubicIntersections = 3; 284 static const int kMaxLineCubicIntersections = 3;
273 SkSTArray<(kMaxLineCubicIntersections - 1) * kMaxLineCubicIntersections, dou ble, true> tVals; 285 SkSTArray<(kMaxLineCubicIntersections - 1) * kMaxLineCubicIntersections, dou ble, true> tVals;
274 line[0] = cubic1[t1Index]; 286 line[0] = cubic1[t1Index];
275 // this variant looks for intersections with the end point and lines paralle l to other points 287 // this variant looks for intersections with the end point and lines paralle l to other points
276 for (int index = 0; index < kPointsInCubic; ++index) { 288 for (int index = 0; index < kPointsInCubic; ++index) {
277 if (index == t1Index) { 289 if (index == t1Index) {
278 continue; 290 continue;
279 } 291 }
280 SkDVector dxy1 = cubic1[index] - line[0]; 292 SkDVector dxy1 = cubic1[index] - line[0];
281 dxy1 /= SkDCubic::gPrecisionUnit; 293 dxy1 /= SkDCubic::gPrecisionUnit;
282 line[1] = line[0] + dxy1; 294 line[1] = line[0] + dxy1;
283 SkDRect lineBounds; 295 SkDRect lineBounds;
284 lineBounds.setBounds(line); 296 lineBounds.setBounds(line);
285 if (!bounds2.intersects(&lineBounds)) { 297 if (!bounds2.intersects(&lineBounds)) {
286 continue; 298 continue;
287 } 299 }
288 SkIntersections local; 300 SkIntersections local;
289 if (!local.intersect(cubic2, line)) { 301 if (!local.intersect(cubic2, line)) {
290 continue; 302 continue;
291 } 303 }
292 for (int idx2 = 0; idx2 < local.used(); ++idx2) { 304 for (int idx2 = 0; idx2 < local.used(); ++idx2) {
293 double foundT = local[0][idx2]; 305 double foundT = local[0][idx2];
294 if (approximately_less_than_zero(foundT) 306 if (approximately_less_than_zero(foundT)
295 || approximately_greater_than_one(foundT)) { 307 || approximately_greater_than_one(foundT)) {
296 continue; 308 continue;
297 } 309 }
298 if (local.pt(idx2).approximatelyEqual(line[0])) { 310 if (local.pt(idx2).approximatelyEqual(line[0])) {
299 if (i.swapped()) { // FIXME: insert should respect swap 311 if (i.swapped()) { // FIXME: insert should respect swap
300 i.insert(foundT, start ? 0 : 1, line[0]); 312 i.insert(foundT, testT, line[0]);
301 } else { 313 } else {
302 i.insert(start ? 0 : 1, foundT, line[0]); 314 i.insert(testT, foundT, line[0]);
303 } 315 }
304 } else { 316 } else {
305 tVals.push_back(foundT); 317 tVals.push_back(foundT);
306 } 318 }
307 } 319 }
308 } 320 }
309 if (tVals.count() == 0) { 321 if (tVals.count() == 0) {
310 return; 322 return;
311 } 323 }
312 SkTQSort<double>(tVals.begin(), tVals.end() - 1); 324 SkTQSort<double>(tVals.begin(), tVals.end() - 1);
313 double tMin1 = start ? 0 : 1 - LINE_FRACTION; 325 double tMin1 = start ? 0 : 1 - LINE_FRACTION;
314 double tMax1 = start ? LINE_FRACTION : 1; 326 double tMax1 = start ? LINE_FRACTION : 1;
315 int tIdx = 0; 327 int tIdx = 0;
316 do { 328 do {
317 int tLast = tIdx; 329 int tLast = tIdx;
318 while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVal s[tIdx])) { 330 while (tLast + 1 < tVals.count() && roughly_equal(tVals[tLast + 1], tVal s[tIdx])) {
319 ++tLast; 331 ++tLast;
320 } 332 }
321 double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0); 333 double tMin2 = SkTMax(tVals[tIdx] - LINE_FRACTION, 0.0);
322 double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0); 334 double tMax2 = SkTMin(tVals[tLast] + LINE_FRACTION, 1.0);
323 int lastUsed = i.used(); 335 int lastUsed = i.used();
324 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i); 336 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
325 if (lastUsed == i.used()) { 337 if (lastUsed == i.used()) {
326 tMin2 = SkTMax(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0); 338 tMin2 = SkTMax(tVals[tIdx] - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
327 tMax2 = SkTMin(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0) ; 339 tMax2 = SkTMin(tVals[tLast] + (1.0 / SkDCubic::gPrecisionUnit), 1.0) ;
328 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i); 340 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
329 } 341 }
330 tIdx = tLast + 1; 342 tIdx = tLast + 1;
331 } while (tIdx < tVals.count()); 343 } while (tIdx < tVals.count());
332 #else
333 const SkDPoint& endPt = cubic1[t1Index];
334 if (!bounds2.contains(endPt)) {
335 return;
336 }
337 // this variant looks for intersections within an 'x' of the endpoint
338 double delta = SkTMax(bounds2.width(), bounds2.height());
339 for (int index = 0; index < 2; ++index) {
340 if (index == 0) {
341 line[0].fY = line[1].fY = endPt.fY;
342 line[0].fX = endPt.fX - delta;
343 line[1].fX = endPt.fX + delta;
344 } else {
345 line[0].fX = line[1].fX = cubic1[t1Index].fX;
346 line[0].fY = endPt.fY - delta;
347 line[1].fY = endPt.fY + delta;
348 }
349 SkIntersections local;
350 local.intersectRay(cubic2, line); // OPTIMIZE: special for horizontal/ve rtical lines
351 int used = local.used();
352 for (int index = 0; index < used; ++index) {
353 double foundT = local[0][index];
354 if (approximately_less_than_zero(foundT) || approximately_greater_th an_one(foundT)) {
355 continue;
356 }
357 if (!local.pt(index).approximatelyEqual(endPt)) {
358 continue;
359 }
360 if (i.swapped()) { // FIXME: insert should respect swap
361 i.insert(foundT, start ? 0 : 1, endPt);
362 } else {
363 i.insert(start ? 0 : 1, foundT, endPt);
364 }
365 return;
366 }
367 }
368 // the above doesn't catch when the end of the cubic missed the other cubic beca use the quad
369 // approximation moved too far away, so something like the below is still needed . The enabled
370 // code above tries to avoid this heavy lifting unless the convex hull intersect ed the cubic.
371 double tMin1 = start ? 0 : 1 - LINE_FRACTION;
372 double tMax1 = start ? LINE_FRACTION : 1;
373 double tMin2 = SkTMax(foundT - LINE_FRACTION, 0.0);
374 double tMax2 = SkTMin(foundT + LINE_FRACTION, 1.0);
375 int lastUsed = i.used();
376 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
377 if (lastUsed == i.used()) {
378 tMin2 = SkTMax(foundT - (1.0 / SkDCubic::gPrecisionUnit), 0.0);
379 tMax2 = SkTMin(foundT + (1.0 / SkDCubic::gPrecisionUnit), 1.0);
380 intersect(cubic1, tMin1, tMax1, cubic2, tMin2, tMax2, 1, i);
381 }
382 #endif
383 return; 344 return;
384 } 345 }
385 346
386 const double CLOSE_ENOUGH = 0.001; 347 const double CLOSE_ENOUGH = 0.001;
387 348
388 static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i , SkDPoint& pt) { 349 static bool closeStart(const SkDCubic& cubic, int cubicIndex, SkIntersections& i , SkDPoint& pt) {
389 if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) { 350 if (i[cubicIndex][0] != 0 || i[cubicIndex][1] > CLOSE_ENOUGH) {
390 return false; 351 return false;
391 } 352 }
392 pt = cubic.xyAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2); 353 pt = cubic.ptAtT((i[cubicIndex][0] + i[cubicIndex][1]) / 2);
393 return true; 354 return true;
394 } 355 }
395 356
396 static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) { 357 static bool closeEnd(const SkDCubic& cubic, int cubicIndex, SkIntersections& i, SkDPoint& pt) {
397 int last = i.used() - 1; 358 int last = i.used() - 1;
398 if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH) { 359 if (i[cubicIndex][last] != 1 || i[cubicIndex][last - 1] < 1 - CLOSE_ENOUGH) {
399 return false; 360 return false;
400 } 361 }
401 pt = cubic.xyAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2); 362 pt = cubic.ptAtT((i[cubicIndex][last] + i[cubicIndex][last - 1]) / 2);
402 return true; 363 return true;
403 } 364 }
404 365
366 static bool only_end_pts_in_common(const SkDCubic& c1, const SkDCubic& c2) {
367 // the idea here is to see at minimum do a quick reject by rotating all points
368 // to either side of the line formed by connecting the endpoints
369 // if the opposite curves points are on the line or on the other side, the
370 // curves at most intersect at the endpoints
371 for (int oddMan = 0; oddMan < 4; ++oddMan) {
372 const SkDPoint* endPt[3];
373 for (int opp = 1; opp < 4; ++opp) {
374 int end = oddMan ^ opp; // choose a value not equal to oddMan
375 endPt[opp - 1] = &c1[end];
376 }
377 for (int triTest = 0; triTest < 3; ++triTest) {
378 double origX = endPt[triTest]->fX;
379 double origY = endPt[triTest]->fY;
380 int oppTest = triTest + 1;
381 if (3 == oppTest) {
382 oppTest = 0;
383 }
384 double adj = endPt[oppTest]->fX - origX;
385 double opp = endPt[oppTest]->fY - origY;
386 double sign = (c1[oddMan].fY - origY) * adj - (c1[oddMan].fX - origX ) * opp;
387 if (approximately_zero(sign)) {
388 goto tryNextHalfPlane;
389 }
390 for (int n = 0; n < 4; ++n) {
391 double test = (c2[n].fY - origY) * adj - (c2[n].fX - origX) * op p;
392 if (test * sign > 0 && !precisely_zero(test)) {
393 goto tryNextHalfPlane;
394 }
395 }
396 }
397 return true;
398 tryNextHalfPlane:
399 ;
400 }
401 return false;
402 }
403
405 int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) { 404 int SkIntersections::intersect(const SkDCubic& c1, const SkDCubic& c2) {
406 ::intersect(c1, 0, 1, c2, 0, 1, 1, *this); 405 bool selfIntersect = &c1 == &c2;
406 if (selfIntersect) {
407 if (c1[0].approximatelyEqualHalf(c1[3])) {
408 insert(0, 1, c1[0]);
409 }
410 } else {
411 for (int i1 = 0; i1 < 4; i1 += 3) {
412 for (int i2 = 0; i2 < 4; i2 += 3) {
413 if (c1[i1].approximatelyEqualHalf(c2[i2])) {
414 insert(i1 >> 1, i2 >> 1, c1[i1]);
415 }
416 }
417 }
418 }
419 SkASSERT(fUsed < 4);
420 if (!selfIntersect) {
421 if (only_end_pts_in_common(c1, c2)) {
422 return fUsed;
423 }
424 if (only_end_pts_in_common(c2, c1)) {
425 return fUsed;
426 }
427 }
428 // quad/quad does linear test here -- cubic does not
429 // cubics which are really lines should have been detected in reduce step ea rlier
430 SkDRect c1Bounds, c2Bounds;
407 // FIXME: pass in cached bounds from caller 431 // FIXME: pass in cached bounds from caller
408 SkDRect c1Bounds, c2Bounds;
409 c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ? 432 c1Bounds.setBounds(c1); // OPTIMIZE use setRawBounds ?
410 c2Bounds.setBounds(c2); 433 c2Bounds.setBounds(c2);
411 intersectEnd(c1, false, c2, c2Bounds, *this); 434 intersectEnd(c1, false, c2, c2Bounds, selfIntersect, *this);
412 intersectEnd(c1, true, c2, c2Bounds, *this); 435 intersectEnd(c1, true, c2, c2Bounds, selfIntersect, *this);
413 bool selfIntersect = &c1 == &c2; 436 if (selfIntersect) {
414 if (!selfIntersect) { 437 if (fUsed) {
438 return fUsed;
439 }
440 } else {
415 swap(); 441 swap();
416 intersectEnd(c2, false, c1, c1Bounds, *this); 442 intersectEnd(c2, false, c1, c1Bounds, false, *this);
417 intersectEnd(c2, true, c1, c1Bounds, *this); 443 intersectEnd(c2, true, c1, c1Bounds, false, *this);
418 swap(); 444 swap();
419 } 445 }
446 // if two ends intersect, check middle for coincidence
447 if (fUsed >= 2) {
448 SkASSERT(!selfIntersect);
449 int last = fUsed - 1;
450 double tRange1 = fT[0][last] - fT[0][0];
451 double tRange2 = fT[1][last] - fT[1][0];
452 for (int index = 1; index < 5; ++index) {
453 double testT1 = fT[0][0] + tRange1 * index / 5;
454 double testT2 = fT[1][0] + tRange2 * index / 5;
455 SkDPoint testPt1 = c1.ptAtT(testT1);
456 SkDPoint testPt2 = c2.ptAtT(testT2);
457 if (!testPt1.approximatelyEqual(testPt2)) {
458 goto skipCoincidence;
459 }
460 }
461 if (fUsed > 2) {
462 fPt[1] = fPt[last];
463 fT[0][1] = fT[0][last];
464 fT[1][1] = fT[1][last];
465 fUsed = 2;
466 }
467 fIsCoincident[0] = fIsCoincident[1] = 0x03;
468 return fUsed;
469 }
470 skipCoincidence:
471 ::intersect(c1, 0, 1, c2, 0, 1, 1, *this);
420 // If an end point and a second point very close to the end is returned, the second 472 // If an end point and a second point very close to the end is returned, the second
421 // point may have been detected because the approximate quads 473 // point may have been detected because the approximate quads
422 // intersected at the end and close to it. Verify that the second point is v alid. 474 // intersected at the end and close to it. Verify that the second point is v alid.
423 if (fUsed <= 1 || coincidentUsed()) { 475 if (fUsed <= 1) {
424 return fUsed; 476 return fUsed;
425 } 477 }
426 SkDPoint pt[2]; 478 SkDPoint pt[2];
427 if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1]) 479 if (closeStart(c1, 0, *this, pt[0]) && closeStart(c2, 1, *this, pt[1])
428 && pt[0].approximatelyEqual(pt[1])) { 480 && pt[0].approximatelyEqual(pt[1])) {
429 removeOne(1); 481 removeOne(1);
430 } 482 }
431 if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1]) 483 if (closeEnd(c1, 0, *this, pt[0]) && closeEnd(c2, 1, *this, pt[1])
432 && pt[0].approximatelyEqual(pt[1])) { 484 && pt[0].approximatelyEqual(pt[1])) {
433 removeOne(used() - 2); 485 removeOne(used() - 2);
434 } 486 }
435 // vet the pairs of t values to see if the mid value is also on the curve. I f so, mark 487 // vet the pairs of t values to see if the mid value is also on the curve. I f so, mark
436 // the span as coincident 488 // the span as coincident
437 if (fUsed >= 2 && !coincidentUsed()) { 489 if (fUsed >= 2 && !coincidentUsed()) {
438 int last = fUsed - 1; 490 int last = fUsed - 1;
439 int match = 0; 491 int match = 0;
440 for (int index = 0; index < last; ++index) { 492 for (int index = 0; index < last; ++index) {
441 double mid1 = (fT[0][index] + fT[0][index + 1]) / 2; 493 double mid1 = (fT[0][index] + fT[0][index + 1]) / 2;
442 double mid2 = (fT[1][index] + fT[1][index + 1]) / 2; 494 double mid2 = (fT[1][index] + fT[1][index + 1]) / 2;
443 pt[0] = c1.xyAtT(mid1); 495 pt[0] = c1.ptAtT(mid1);
444 pt[1] = c2.xyAtT(mid2); 496 pt[1] = c2.ptAtT(mid2);
445 if (pt[0].approximatelyEqual(pt[1])) { 497 if (pt[0].approximatelyEqual(pt[1])) {
446 match |= 1 << index; 498 match |= 1 << index;
447 } 499 }
448 } 500 }
449 if (match) { 501 if (match) {
450 if (((match + 1) & match) != 0) { 502 if (((match + 1) & match) != 0) {
451 SkDebugf("%s coincident hole\n", __FUNCTION__); 503 SkDebugf("%s coincident hole\n", __FUNCTION__);
452 } 504 }
453 // for now, assume that everything from start to finish is coinciden t 505 // for now, assume that everything from start to finish is coinciden t
454 if (fUsed > 2) { 506 if (fUsed > 2) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 } 539 }
488 (void) intersect(c, c); 540 (void) intersect(c, c);
489 if (used() > 0) { 541 if (used() > 0) {
490 SkASSERT(used() == 1); 542 SkASSERT(used() == 1);
491 if (fT[0][0] > fT[1][0]) { 543 if (fT[0][0] > fT[1][0]) {
492 swapPts(); 544 swapPts();
493 } 545 }
494 } 546 }
495 return used(); 547 return used();
496 } 548 }
OLDNEW
« no previous file with comments | « no previous file | src/pathops/SkDCubicLineIntersection.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698