| 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 "PathOpsCubicIntersectionTestData.h" | 7 #include "PathOpsCubicIntersectionTestData.h" |
| 8 #include "PathOpsTestCommon.h" | 8 #include "PathOpsTestCommon.h" |
| 9 #include "SkIntersections.h" | 9 #include "SkIntersections.h" |
| 10 #include "SkPathOpsRect.h" | 10 #include "SkPathOpsRect.h" |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 double tt1 = tIntersections[0][pt]; | 54 double tt1 = tIntersections[0][pt]; |
| 55 SkDPoint xy1 = cubic1.ptAtT(tt1); | 55 SkDPoint xy1 = cubic1.ptAtT(tt1); |
| 56 double tt2 = tIntersections[1][pt]; | 56 double tt2 = tIntersections[1][pt]; |
| 57 SkDPoint xy2 = cubic2.ptAtT(tt2); | 57 SkDPoint xy2 = cubic2.ptAtT(tt2); |
| 58 if (!xy1.approximatelyEqual(xy2)) { | 58 if (!xy1.approximatelyEqual(xy2)) { |
| 59 SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", | 59 SkDebugf("%s [%d,%d] x!= t1=%g (%g,%g) t2=%g (%g,%g)\n", |
| 60 __FUNCTION__, (int)index, pt, tt1, xy1.fX, xy1.fY, tt2, xy2.
fX, xy2.fY); | 60 __FUNCTION__, (int)index, pt, tt1, xy1.fX, xy1.fY, tt2, xy2.
fX, xy2.fY); |
| 61 } | 61 } |
| 62 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); | 62 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); |
| 63 } | 63 } |
| 64 reporter->bumpTestCount(); |
| 64 } | 65 } |
| 65 } | 66 } |
| 66 | 67 |
| 67 static const SkDCubic testSet[] = { | 68 static const SkDCubic testSet[] = { |
| 68 // FIXME: uncommenting these two will cause this to fail | 69 // FIXME: uncommenting these two will cause this to fail |
| 69 // this results in two curves very nearly but not exactly coincident | 70 // this results in two curves very nearly but not exactly coincident |
| 70 #if 0 | 71 #if 0 |
| 71 {{{67.426548091427676, 37.993772624988935}, {23.483695892376684, 90.476863174921
306}, | 72 {{{67.426548091427676, 37.993772624988935}, {23.483695892376684, 90.476863174921
306}, |
| 72 {35.597065061143162, 79.872482633158796}, {75.38634169631932, 18.244890038
969412}}}, | 73 {35.597065061143162, 79.872482633158796}, {75.38634169631932, 18.244890038
969412}}}, |
| 73 {{{67.4265481, 37.9937726}, {23.4836959, 90.4768632}, {35.5970651, 79.8724826}, | 74 {{{67.4265481, 37.9937726}, {23.4836959, 90.4768632}, {35.5970651, 79.8724826}, |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 | 157 |
| 157 {{{18.1312339, 31.6473732}, {95.5711034, 63.5350219}, {92.3283165, 62.0158945}, | 158 {{{18.1312339, 31.6473732}, {95.5711034, 63.5350219}, {92.3283165, 62.0158945}, |
| 158 {18.5656052, 32.1268808}}}, | 159 {18.5656052, 32.1268808}}}, |
| 159 {{{97.402018, 35.7169972}, {33.1127443, 25.8935163}, {1.13970027, 54.9424981}, | 160 {{{97.402018, 35.7169972}, {33.1127443, 25.8935163}, {1.13970027, 54.9424981}, |
| 160 {56.4860195, 60.529264}}}, | 161 {56.4860195, 60.529264}}}, |
| 161 }; | 162 }; |
| 162 | 163 |
| 163 const size_t testSetCount = SK_ARRAY_COUNT(testSet); | 164 const size_t testSetCount = SK_ARRAY_COUNT(testSet); |
| 164 | 165 |
| 165 static const SkDCubic newTestSet[] = { | 166 static const SkDCubic newTestSet[] = { |
| 166 {{{134, 11414}, {131.990234375, 11414}, {130.32666015625, 11415.482421875}, {130
.04275512695312, 11417.4130859375}}}, | 167 #if 0 // FIXME: asserts coincidence, not working yet |
| 168 {{{195, 785}, {124.30755615234375, 785}, {67, 841.85986328125}, {67, 912}}}, |
| 169 {{{67, 913}, {67, 842.30755615234375}, {123.85984039306641, 785}, {194, 785}}}, |
| 170 #endif |
| 171 |
| 172 {{{399,657}, {399,661.970581}, {403.029449,666}, {408,666}}}, |
| 173 {{{406,666}, {402.686279,666}, {400,663.313721}, {400,660}}}, |
| 174 |
| 175 {{{0,5}, {3,5}, {3,0}, {3,2}}}, |
| 176 {{{0,3}, {2,3}, {5,0}, {5,3}}}, |
| 177 |
| 167 {{{132, 11419}, {130.89543151855469, 11419}, {130, 11418.1044921875}, {130, 1141
7}}}, | 178 {{{132, 11419}, {130.89543151855469, 11419}, {130, 11418.1044921875}, {130, 1141
7}}}, |
| 168 | 179 |
| 169 {{{3, 4}, {1, 5}, {4, 3}, {6, 4}}}, | 180 {{{3, 4}, {1, 5}, {4, 3}, {6, 4}}}, |
| 170 {{{3, 4}, {4, 6}, {4, 3}, {5, 1}}}, | 181 {{{3, 4}, {4, 6}, {4, 3}, {5, 1}}}, |
| 171 | 182 |
| 172 {{{130.04275512695312, 11417.413085937500 }, | 183 {{{130.04275512695312, 11417.413085937500 }, |
| 173 {130.23312377929687, 11418.319335937500 }, | 184 {130.23312377929687, 11418.319335937500 }, |
| 174 {131.03707885742187, 11419.000000000000 }, | 185 {131.03707885742187, 11419.000000000000 }, |
| 175 {132.00000000000000, 11419.000000000000 }}}, | 186 {132.00000000000000, 11419.000000000000 }}}, |
| 176 | 187 |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 276 | 287 |
| 277 {{{0, 6}, {1, 2}, {1, 0}, {1, 0}}}, | 288 {{{0, 6}, {1, 2}, {1, 0}, {1, 0}}}, |
| 278 {{{0, 1}, {0, 1}, {6, 0}, {2, 1}}}, | 289 {{{0, 1}, {0, 1}, {6, 0}, {2, 1}}}, |
| 279 | 290 |
| 280 {{{0, 2}, {0, 1}, {3, 0}, {1, 0}}}, | 291 {{{0, 2}, {0, 1}, {3, 0}, {1, 0}}}, |
| 281 {{{0, 3}, {0, 1}, {2, 0}, {1, 0}}}, | 292 {{{0, 3}, {0, 1}, {2, 0}, {1, 0}}}, |
| 282 }; | 293 }; |
| 283 | 294 |
| 284 const size_t newTestSetCount = SK_ARRAY_COUNT(newTestSet); | 295 const size_t newTestSetCount = SK_ARRAY_COUNT(newTestSet); |
| 285 | 296 |
| 286 static void oneOff(skiatest::Reporter* reporter, const SkDCubic& cubic1, const S
kDCubic& cubic2) { | 297 static void oneOff(skiatest::Reporter* reporter, const SkDCubic& cubic1, const S
kDCubic& cubic2, |
| 298 bool coin) { |
| 287 SkASSERT(ValidCubic(cubic1)); | 299 SkASSERT(ValidCubic(cubic1)); |
| 288 SkASSERT(ValidCubic(cubic2)); | 300 SkASSERT(ValidCubic(cubic2)); |
| 289 #if ONE_OFF_DEBUG | 301 #if ONE_OFF_DEBUG |
| 290 SkDebugf("computed quadratics given\n"); | 302 SkDebugf("computed quadratics given\n"); |
| 291 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n"
, | 303 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n"
, |
| 292 cubic1[0].fX, cubic1[0].fY, cubic1[1].fX, cubic1[1].fY, | 304 cubic1[0].fX, cubic1[0].fY, cubic1[1].fX, cubic1[1].fY, |
| 293 cubic1[2].fX, cubic1[2].fY, cubic1[3].fX, cubic1[3].fY); | 305 cubic1[2].fX, cubic1[2].fY, cubic1[3].fX, cubic1[3].fY); |
| 294 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n"
, | 306 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n"
, |
| 295 cubic2[0].fX, cubic2[0].fY, cubic2[1].fX, cubic2[1].fY, | 307 cubic2[0].fX, cubic2[0].fY, cubic2[1].fX, cubic2[1].fY, |
| 296 cubic2[2].fX, cubic2[2].fY, cubic2[3].fX, cubic2[3].fY); | 308 cubic2[2].fX, cubic2[2].fY, cubic2[3].fX, cubic2[3].fY); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 310 #if ONE_OFF_DEBUG | 322 #if ONE_OFF_DEBUG |
| 311 SkDebugf("computed quadratics set 2\n"); | 323 SkDebugf("computed quadratics set 2\n"); |
| 312 for (int index = 0; index < quads2.count(); ++index) { | 324 for (int index = 0; index < quads2.count(); ++index) { |
| 313 const SkDQuad& q = quads2[index]; | 325 const SkDQuad& q = quads2[index]; |
| 314 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].fX,
q[0].fY, | 326 SkDebugf(" {{%1.9g,%1.9g}, {%1.9g,%1.9g}, {%1.9g,%1.9g}},\n", q[0].fX,
q[0].fY, |
| 315 q[1].fX, q[1].fY, q[2].fX, q[2].fY); | 327 q[1].fX, q[1].fY, q[2].fX, q[2].fY); |
| 316 } | 328 } |
| 317 #endif | 329 #endif |
| 318 SkIntersections intersections; | 330 SkIntersections intersections; |
| 319 intersections.intersect(cubic1, cubic2); | 331 intersections.intersect(cubic1, cubic2); |
| 332 REPORTER_ASSERT(reporter, !coin || intersections.used() == 2); |
| 320 double tt1, tt2; | 333 double tt1, tt2; |
| 321 SkDPoint xy1, xy2; | 334 SkDPoint xy1, xy2; |
| 322 for (int pt3 = 0; pt3 < intersections.used(); ++pt3) { | 335 for (int pt3 = 0; pt3 < intersections.used(); ++pt3) { |
| 323 tt1 = intersections[0][pt3]; | 336 tt1 = intersections[0][pt3]; |
| 324 xy1 = cubic1.ptAtT(tt1); | 337 xy1 = cubic1.ptAtT(tt1); |
| 325 tt2 = intersections[1][pt3]; | 338 tt2 = intersections[1][pt3]; |
| 326 xy2 = cubic2.ptAtT(tt2); | 339 xy2 = cubic2.ptAtT(tt2); |
| 327 const SkDPoint& iPt = intersections.pt(pt3); | 340 const SkDPoint& iPt = intersections.pt(pt3); |
| 328 #if ONE_OFF_DEBUG | 341 #if ONE_OFF_DEBUG |
| 329 SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1
.9g\n", | 342 SkDebugf("%s t1=%1.9g (%1.9g, %1.9g) (%1.9g, %1.9g) (%1.9g, %1.9g) t2=%1
.9g\n", |
| 330 __FUNCTION__, tt1, xy1.fX, xy1.fY, iPt.fX, | 343 __FUNCTION__, tt1, xy1.fX, xy1.fY, iPt.fX, |
| 331 iPt.fY, xy2.fX, xy2.fY, tt2); | 344 iPt.fY, xy2.fX, xy2.fY, tt2); |
| 332 #endif | 345 #endif |
| 333 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(iPt)); | 346 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(iPt)); |
| 334 REPORTER_ASSERT(reporter, xy2.approximatelyEqual(iPt)); | 347 REPORTER_ASSERT(reporter, xy2.approximatelyEqual(iPt)); |
| 335 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); | 348 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); |
| 336 } | 349 } |
| 350 reporter->bumpTestCount(); |
| 337 } | 351 } |
| 338 | 352 |
| 339 static void oneOff(skiatest::Reporter* reporter, int outer, int inner) { | 353 static void oneOff(skiatest::Reporter* reporter, int outer, int inner) { |
| 340 const SkDCubic& cubic1 = testSet[outer]; | 354 const SkDCubic& cubic1 = testSet[outer]; |
| 341 const SkDCubic& cubic2 = testSet[inner]; | 355 const SkDCubic& cubic2 = testSet[inner]; |
| 342 oneOff(reporter, cubic1, cubic2); | 356 oneOff(reporter, cubic1, cubic2, false); |
| 343 } | 357 } |
| 344 | 358 |
| 345 static void newOneOff(skiatest::Reporter* reporter, int outer, int inner) { | 359 static void newOneOff(skiatest::Reporter* reporter, int outer, int inner) { |
| 346 const SkDCubic& cubic1 = newTestSet[outer]; | 360 const SkDCubic& cubic1 = newTestSet[outer]; |
| 347 const SkDCubic& cubic2 = newTestSet[inner]; | 361 const SkDCubic& cubic2 = newTestSet[inner]; |
| 348 oneOff(reporter, cubic1, cubic2); | 362 oneOff(reporter, cubic1, cubic2, false); |
| 349 } | 363 } |
| 350 | 364 |
| 351 static void oneOffTests(skiatest::Reporter* reporter) { | 365 static void oneOffTests(skiatest::Reporter* reporter) { |
| 352 for (size_t outer = 0; outer < testSetCount - 1; ++outer) { | 366 for (size_t outer = 0; outer < testSetCount - 1; ++outer) { |
| 353 for (size_t inner = outer + 1; inner < testSetCount; ++inner) { | 367 for (size_t inner = outer + 1; inner < testSetCount; ++inner) { |
| 354 oneOff(reporter, outer, inner); | 368 oneOff(reporter, outer, inner); |
| 355 } | 369 } |
| 356 } | 370 } |
| 357 for (size_t outer = 0; outer < newTestSetCount - 1; ++outer) { | 371 for (size_t outer = 0; outer < newTestSetCount - 1; ++outer) { |
| 358 for (size_t inner = outer + 1; inner < newTestSetCount; ++inner) { | 372 for (size_t inner = outer + 1; inner < newTestSetCount; ++inner) { |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 405 #endif | 419 #endif |
| 406 REPORTER_ASSERT(reporter, 0); | 420 REPORTER_ASSERT(reporter, 0); |
| 407 } | 421 } |
| 408 for (int pt = 0; pt < intersections2.used(); ++pt) { | 422 for (int pt = 0; pt < intersections2.used(); ++pt) { |
| 409 double tt1 = intersections2[0][pt]; | 423 double tt1 = intersections2[0][pt]; |
| 410 SkDPoint xy1 = cubic1.ptAtT(tt1); | 424 SkDPoint xy1 = cubic1.ptAtT(tt1); |
| 411 double tt2 = intersections2[1][pt]; | 425 double tt2 = intersections2[1][pt]; |
| 412 SkDPoint xy2 = cubic2.ptAtT(tt2); | 426 SkDPoint xy2 = cubic2.ptAtT(tt2); |
| 413 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); | 427 REPORTER_ASSERT(reporter, xy1.approximatelyEqual(xy2)); |
| 414 } | 428 } |
| 429 reporter->bumpTestCount(); |
| 415 } | 430 } |
| 416 } | 431 } |
| 417 | 432 |
| 418 static void intersectionFinder(int index0, int index1, double t1Seed, double t2S
eed, | 433 static void intersectionFinder(int index0, int index1, double t1Seed, double t2S
eed, |
| 419 double t1Step, double t2Step) { | 434 double t1Step, double t2Step) { |
| 420 const SkDCubic& cubic1 = newTestSet[index0]; | 435 const SkDCubic& cubic1 = newTestSet[index0]; |
| 421 const SkDCubic& cubic2 = newTestSet[index1]; | 436 const SkDCubic& cubic2 = newTestSet[index1]; |
| 422 SkDPoint t1[3], t2[3]; | 437 SkDPoint t1[3], t2[3]; |
| 423 bool toggle = true; | 438 bool toggle = true; |
| 424 do { | 439 do { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 552 SkDebugf("\n"); | 567 SkDebugf("\n"); |
| 553 #endif | 568 #endif |
| 554 SkIntersections i; | 569 SkIntersections i; |
| 555 int result = i.intersect(cubic); | 570 int result = i.intersect(cubic); |
| 556 REPORTER_ASSERT(reporter, result == 1); | 571 REPORTER_ASSERT(reporter, result == 1); |
| 557 REPORTER_ASSERT(reporter, i.used() == 1); | 572 REPORTER_ASSERT(reporter, i.used() == 1); |
| 558 REPORTER_ASSERT(reporter, !approximately_equal(i[0][0], i[1][0])); | 573 REPORTER_ASSERT(reporter, !approximately_equal(i[0][0], i[1][0])); |
| 559 SkDPoint pt1 = cubic.ptAtT(i[0][0]); | 574 SkDPoint pt1 = cubic.ptAtT(i[0][0]); |
| 560 SkDPoint pt2 = cubic.ptAtT(i[1][0]); | 575 SkDPoint pt2 = cubic.ptAtT(i[1][0]); |
| 561 REPORTER_ASSERT(reporter, pt1.approximatelyEqual(pt2)); | 576 REPORTER_ASSERT(reporter, pt1.approximatelyEqual(pt2)); |
| 577 reporter->bumpTestCount(); |
| 562 } | 578 } |
| 563 | 579 |
| 564 static void cubicIntersectionSelfTest(skiatest::Reporter* reporter) { | 580 static void cubicIntersectionSelfTest(skiatest::Reporter* reporter) { |
| 565 size_t firstFail = 0; | 581 size_t firstFail = 0; |
| 566 for (size_t index = firstFail; index < selfSetCount; ++index) { | 582 for (size_t index = firstFail; index < selfSetCount; ++index) { |
| 567 selfOneOff(reporter, index); | 583 selfOneOff(reporter, index); |
| 568 } | 584 } |
| 569 } | 585 } |
| 570 | 586 |
| 587 static const SkDCubic coinSet[] = { |
| 588 {{{317, 711}, {322.52285766601562, 711}, {327, 715.4771728515625}, {327, 721
}}}, |
| 589 {{{324.07107543945312, 713.928955078125}, {324.4051513671875, 714.2630004882
8125}, |
| 590 {324.71566772460937, 714.62060546875}, {325, 714.9990234375}}}, |
| 591 |
| 592 {{{2, 3}, {0, 4}, {3, 2}, {5, 3}}}, |
| 593 {{{2, 3}, {0, 4}, {3, 2}, {5, 3}}}, |
| 594 }; |
| 595 |
| 596 size_t coinSetCount = SK_ARRAY_COUNT(coinSet); |
| 597 |
| 598 static void coinOneOff(skiatest::Reporter* reporter, int index) { |
| 599 const SkDCubic& cubic1 = coinSet[index]; |
| 600 const SkDCubic& cubic2 = coinSet[index + 1]; |
| 601 oneOff(reporter, cubic1, cubic2, true); |
| 602 } |
| 603 |
| 604 static void cubicIntersectionCoinTest(skiatest::Reporter* reporter) { |
| 605 size_t firstFail = 0; |
| 606 for (size_t index = firstFail; index < coinSetCount; index += 2) { |
| 607 coinOneOff(reporter, index); |
| 608 } |
| 609 } |
| 610 |
| 611 static void PathOpsCubicCoinOneOffTest(skiatest::Reporter* reporter) { |
| 612 coinOneOff(reporter, 0); |
| 613 } |
| 614 |
| 571 static void PathOpsCubicIntersectionOneOffTest(skiatest::Reporter* reporter) { | 615 static void PathOpsCubicIntersectionOneOffTest(skiatest::Reporter* reporter) { |
| 572 newOneOff(reporter, 0, 1); | 616 newOneOff(reporter, 0, 1); |
| 573 } | 617 } |
| 574 | 618 |
| 575 static void PathOpsCubicSelfOneOffTest(skiatest::Reporter* reporter) { | 619 static void PathOpsCubicSelfOneOffTest(skiatest::Reporter* reporter) { |
| 576 selfOneOff(reporter, 0); | 620 selfOneOff(reporter, 0); |
| 577 } | 621 } |
| 578 | 622 |
| 579 static void PathOpsCubicIntersectionTest(skiatest::Reporter* reporter) { | 623 static void PathOpsCubicIntersectionTest(skiatest::Reporter* reporter) { |
| 580 oneOffTests(reporter); | 624 oneOffTests(reporter); |
| 581 cubicIntersectionSelfTest(reporter); | 625 cubicIntersectionSelfTest(reporter); |
| 626 cubicIntersectionCoinTest(reporter); |
| 582 standardTestCases(reporter); | 627 standardTestCases(reporter); |
| 583 if (false) CubicIntersection_IntersectionFinder(); | 628 if (false) CubicIntersection_IntersectionFinder(); |
| 584 if (false) CubicIntersection_RandTest(reporter); | 629 if (false) CubicIntersection_RandTest(reporter); |
| 585 } | 630 } |
| 586 | 631 |
| 587 #include "TestClassDef.h" | 632 #include "TestClassDef.h" |
| 588 DEFINE_TESTCLASS_SHORT(PathOpsCubicIntersectionTest) | 633 DEFINE_TESTCLASS_SHORT(PathOpsCubicIntersectionTest) |
| 589 | 634 |
| 590 DEFINE_TESTCLASS_SHORT(PathOpsCubicIntersectionOneOffTest) | 635 DEFINE_TESTCLASS_SHORT(PathOpsCubicIntersectionOneOffTest) |
| 591 | 636 |
| 592 DEFINE_TESTCLASS_SHORT(PathOpsCubicSelfOneOffTest) | 637 DEFINE_TESTCLASS_SHORT(PathOpsCubicSelfOneOffTest) |
| 638 |
| 639 DEFINE_TESTCLASS_SHORT(PathOpsCubicCoinOneOffTest) |
| OLD | NEW |