133 unsigned N = wiggle.order() + 1;
134 std::vector<Coord> left(
N), right(
N);
135 std::vector<Coord> left2(
N), right2(
N);
138 for (
unsigned i = 0; i < 10000; ++i) {
139 double t = g_random_double_range(0, 1);
141 double v = casteljau_subdivision<double>(t, &wiggle[0], &left[0], &right[0], wiggle.order());
142 EXPECT_near(v, vok, eps);
143 EXPECT_EQ(left[0], wiggle.at0());
144 EXPECT_EQ(left[wiggle.order()], right[0]);
145 EXPECT_EQ(right[wiggle.order()], wiggle.at1());
147 double vl = casteljau_subdivision<double>(t, &wiggle[0], &left2[0], NULL, wiggle.order());
148 double vr = casteljau_subdivision<double>(t, &wiggle[0], NULL, &right2[0], wiggle.order());
150 EXPECT_near(vr, vok, eps);
151 EXPECT_vector_near(left2, left, eps);
152 EXPECT_vector_equal(right2, right);
154 double vnone = casteljau_subdivision<double>(t, &wiggle[0], NULL, NULL, wiggle.order());
155 EXPECT_near(vnone, vok, 1e-12);
419 std::vector<XTest> tests;
422 tests.emplace_back();
423 tests.back().a = D2Bez(
Bezier(-3.3, -3.3, 0, 3.3, 3.3),
Bezier(1.3, -0.7, 2.3, -0.7, 1.3));
424 tests.back().b = D2Bez(
Bezier(-4.0, -4.0, 0, 4.0, 4.0),
Bezier(-0.35, 3.0, -2.6, 3.0, -0.35));
425 tests.back().s.resize(4);
426 tests.back().s[0] = XPt(-3.12109, 0.76362, 0.09834, 0.20604);
427 tests.back().s[1] = XPt(-1.67341, 0.60298, 0.32366, 0.35662);
428 tests.back().s[2] = XPt(1.67341, 0.60298, 0.67634, 0.64338);
429 tests.back().s[3] = XPt(3.12109, 0.76362, 0.90166, 0.79396);
432 tests.emplace_back();
433 tests.back().a = D2Bez(
Bezier(0, 0, 3, 3),
Bezier(0, 14, -9, 5));
434 tests.back().b = D2Bez(
Bezier(-1, 13, -10, 4),
Bezier(4, 4, 1, 1));
435 tests.back().s.resize(9);
436 tests.back().s[0] = XPt(0.00809, 1.17249, 0.03029, 0.85430);
437 tests.back().s[1] = XPt(0.02596, 1.97778, 0.05471, 0.61825);
438 tests.back().s[2] = XPt(0.17250, 3.99191, 0.14570, 0.03029);
439 tests.back().s[3] = XPt(0.97778, 3.97404, 0.38175, 0.05471);
440 tests.back().s[4] = XPt(1.5, 2.5, 0.5, 0.5);
441 tests.back().s[5] = XPt(2.02221, 1.02596, 0.61825, 0.94529);
442 tests.back().s[6] = XPt(2.82750, 1.00809, 0.85430, 0.96971);
443 tests.back().s[7] = XPt(2.97404, 3.02221, 0.94529, 0.38175);
444 tests.back().s[8] = XPt(2.99191, 3.82750, 0.96971, 0.14570);
447 tests.emplace_back();
448 tests.back().a = D2Bez(
Bezier(-5, -5, -3, 0, 3, 5, 5),
Bezier(0, 3.555, -1, 4.17, -1, 3.555, 0));
449 tests.back().b = D2Bez(
Bezier(-6, -6, -3, 0, 3, 6, 6),
Bezier(3, -0.555, 4, -1.17, 4, -0.555, 3));
450 tests.back().s.resize(6);
451 tests.back().s[0] = XPt(-3.64353, 1.49822, 0.23120, 0.27305);
452 tests.back().s[1] = XPt(-2.92393, 1.50086, 0.29330, 0.32148);
453 tests.back().s[2] = XPt(-0.77325, 1.49989, 0.44827, 0.45409);
454 tests.back().s[3] = XPt(0.77325, 1.49989, 0.55173, 0.54591);
455 tests.back().s[4] = XPt(2.92393, 1.50086, 0.70670, 0.67852);
456 tests.back().s[5] = XPt(3.64353, 1.49822, 0.76880, 0.72695);
459 tests.emplace_back();
460 tests.back().a = D2Bez(
Bezier(-4, -10, -2, -2, 2, 2, 10, 4),
Bezier(0, 6, 6, 0, 0, 6, 6, 0));
461 tests.back().b = D2Bez(
Bezier(-8, 0, 8),
Bezier(1, 6, 1));
462 tests.back().s.resize(4);
463 tests.back().s[0] = XPt(-5.69310, 2.23393, 0.06613, 0.14418);
464 tests.back().s[1] = XPt(-2.68113, 3.21920, 0.35152, 0.33243);
465 tests.back().s[2] = XPt(2.68113, 3.21920, 0.64848, 0.66757);
466 tests.back().s[3] = XPt(5.69310, 2.23393, 0.93387, 0.85582);
470 for (
unsigned i = 0; i < tests.size(); ++i) {
472 std::vector<CurveIntersection> xs;
473 xs = a.intersect(b, 1e-8);
474 std::sort(xs.begin(), xs.end(), CILess());
478 <<
"===============================\n"
479 <<
"=== Intersection Testcase " << i+1 <<
" ===\n"
480 <<
"===============================\n" << std::endl;
482 EXPECT_EQ(xs.size(), tests[i].s.size());
485 for (
unsigned j = 0; j < std::min(xs.size(), tests[i].s.size()); ++j) {
486 std::cout << xs[j].first <<
" = " << a.pointAt(xs[j].first) <<
" "
487 << xs[j].second <<
" = " << b.pointAt(xs[j].second) <<
"\n"
488 << tests[i].s[j].ta <<
" = " << tests[i].a.valueAt(tests[i].s[j].ta) <<
" "
489 << tests[i].s[j].tb <<
" = " << tests[i].b.valueAt(tests[i].s[j].tb) << std::endl;
492 EXPECT_intersections_valid(a, b, xs, 1e-6);
497 Coord a5x[] = {-1.5, -1.5, -10, -10, 0, 10, 10, 1.5, 1.5};
498 Coord a5y[] = {0, -8, -8, 9, 9, 9, -8, -8, 0};
499 Coord b5x[] = {-3, -12, 0, 12, 3};
500 Coord b5y[] = {-5, 8, 2.062507, 8, -5};
501 Coord p5x[] = {-3.60359, -5.44653, 0, 5.44653, 3.60359};
502 Coord p5y[] = {-4.10631, -0.76332, 4.14844, -0.76332, -4.10631};
503 Coord p5ta[] = {0.01787, 0.10171, 0.5, 0.89829, 0.98213};
504 Coord p5tb[] = {0.12443, 0.28110, 0.5, 0.71890, 0.87557};
506 Coord a6x[] = {5, 14, 10, -12, -12, -2};
507 Coord a6y[] = {1, 6, -6, -6, 2, 2};
508 Coord b6x[] = {0, 2, -10.5, -10.5, 3.5, 3, 8, 6};
509 Coord b6y[] = {0, -8, -8, 9, 9, -4.129807, -4.129807, 3};
510 Coord p6x[] = {6.29966, 5.87601, 0.04246, -4.67397, -3.57214};
511 Coord p6y[] = {1.63288, -0.86192, -2.38219, -2.17973, 1.91463};
512 Coord p6ta[] = {0.03184, 0.33990, 0.49353, 0.62148, 0.96618};
513 Coord p6tb[] = {0.96977, 0.85797, 0.05087, 0.28232, 0.46102};
518TEST_F(BezierTest, QuadraticIntersectLineSeg)
520 double const EPS = 1e-12;
528 auto const endpoint_intersections = bow.intersect(highhoriz, EPS);
529 EXPECT_EQ(endpoint_intersections.size(), 2);
530 EXPECT_intersections_valid(bow, highhoriz, endpoint_intersections, EPS);
531 for (
auto const &ex : endpoint_intersections) {
532 EXPECT_DOUBLE_EQ(ex.point()[
Y], 0.0);
535 auto const mid_intersections = bow.intersect(midhoriz, EPS);
536 EXPECT_EQ(mid_intersections.size(), 2);
537 EXPECT_intersections_valid(bow, midhoriz, mid_intersections, EPS);
538 for (
auto const &mx : mid_intersections) {
539 EXPECT_DOUBLE_EQ(mx.point()[
Y], 0.25);
542 auto const tangent_intersection = bow.intersect(lowhoriz, EPS);
543 EXPECT_EQ(tangent_intersection.size(), 1);
544 EXPECT_intersections_valid(bow, lowhoriz, tangent_intersection, EPS);
545 for (
auto const &tx : tangent_intersection) {
546 EXPECT_DOUBLE_EQ(tx.point()[
Y], 0.5);
549 auto no_intersections = bow.intersect(noninters, EPS);
550 EXPECT_TRUE(no_intersections.empty());
552 no_intersections = bow.intersect(noninters2, EPS);
553 EXPECT_TRUE(no_intersections.empty());