2024-05-29 16:29:08 +10:00
|
|
|
#include <cruft/util/bezier.hpp>
|
2015-01-22 14:57:57 +11:00
|
|
|
|
2024-05-29 16:29:08 +10:00
|
|
|
#include <cruft/util/tap.hpp>
|
2015-01-22 14:57:57 +11:00
|
|
|
|
|
|
|
#include <cstdlib>
|
|
|
|
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2018-08-05 14:42:02 +10:00
|
|
|
template <size_t> void test_eval (cruft::TAP::logger&);
|
|
|
|
template <size_t> void test_intersect (cruft::TAP::logger&);
|
|
|
|
template <size_t> void test_region (cruft::TAP::logger&);
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_eval<1> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<1> b1 ({{ 0.f, 0.f},
|
2015-01-29 15:47:40 +11:00
|
|
|
{100.f, 100.f}});
|
|
|
|
|
|
|
|
auto p0 = b1.eval(0.f);
|
|
|
|
auto p1 = b1.eval(1.f);
|
|
|
|
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (p0, b1[0], "eval bezier-1 extrema");
|
|
|
|
tap.expect_eq (p1, b1[1], "eval bezier-1 extrema");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
auto px = b1.eval(0.5f);
|
|
|
|
auto rx = b1[0] + 0.5f * (b1[1]-b1[0]);
|
2015-04-13 16:45:56 +10:00
|
|
|
|
|
|
|
tap.expect_eq (px, rx, "eval bezier-1 midpoint");
|
2015-01-29 15:47:40 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_eval<2> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<2> b2 ({{ 0.f, 0.f},
|
2015-01-29 15:47:40 +11:00
|
|
|
{ 50.f, 50.f},
|
|
|
|
{100.f, 100.f}});
|
|
|
|
|
|
|
|
auto p0 = b2.eval(0.f);
|
|
|
|
auto p2 = b2.eval(1.f);
|
|
|
|
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (p0, b2[0], "eval bezier-2 extrema");
|
|
|
|
tap.expect_eq (p2, b2[2], "eval bezier-2 extrema");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
auto px = b2.eval(0.5f);
|
|
|
|
auto rx = b2[0] + 0.5f * (b2[2]-b2[0]);
|
2015-04-13 16:45:56 +10:00
|
|
|
|
|
|
|
tap.expect_eq (px, rx, "eval bezier-2 midpoint");
|
2015-01-29 15:47:40 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_eval<3> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<3> b3 ({{ 0.f, 0.f },
|
2015-01-29 15:47:40 +11:00
|
|
|
{ 33.f, 33.f },
|
|
|
|
{ 67.f, 67.f },
|
|
|
|
{ 100.f, 100.f }});
|
|
|
|
|
|
|
|
auto p0 = b3.eval (0.f);
|
|
|
|
auto p3 = b3.eval (1.f);
|
|
|
|
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (p0, b3[0], "eval bezier-3 extrema");
|
|
|
|
tap.expect_eq (p3, b3[3], "eval bezier-3 extrema");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
auto px = b3.eval (0.5f);
|
|
|
|
auto rx = b3[0] + 0.5f * (b3[3] - b3[0]);
|
2015-04-13 16:45:56 +10:00
|
|
|
|
|
|
|
tap.expect_eq (px, rx, "eval bezier-3 midpoint");
|
2015-01-29 15:47:40 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_intersect<1> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
|
|
|
// A line from (0,0) to (100,100)
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<1> b1 ({{0.f, 0.f}, {100.f, 100.f}});
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Through the centre
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (b1.intersections ({0.f, 100.f}, {100.f, 0.f}),
|
|
|
|
1u,
|
|
|
|
"intersect bezier-1 centre");
|
|
|
|
tap.expect_eq (b1.intersections ({100.f, 0.f}, {0.f, 100.f}),
|
|
|
|
1u,
|
|
|
|
"intersect bezier-1 centre");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Coincident with endpoints
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (b1.intersections ({0.f, 0.f}, {1.f,0.f}),
|
|
|
|
1u,
|
|
|
|
"intersect bezier-1 endpoints");
|
|
|
|
tap.expect_eq (b1.intersections ({100.f, 100.f}, {100.f,0.f}),
|
|
|
|
1u,
|
|
|
|
"intersect bezier-1 endpoints");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Co-planar
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (b1.intersections ({0.f, 0.f}, {1.f, 1.f}),
|
|
|
|
1u,
|
|
|
|
"intersect bezier-1 co-planar");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Underneath
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (b1.intersections ({1000.f, -10.f}, {-1000.f, -10.f}),
|
|
|
|
0u,
|
|
|
|
"intersect bezier-1 under");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Above
|
2015-04-13 16:45:56 +10:00
|
|
|
tap.expect_eq (b1.intersections ({1000.f, 110.f}, {-1000.f, 110.f}),
|
|
|
|
0u,
|
|
|
|
"intersect bezier-1 above");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_intersect<2> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
|
|
|
// A linear curve from (0,0) to (100,100)
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<2> b2 ({{ 0.0f, 0.0f},
|
2015-01-29 15:47:40 +11:00
|
|
|
{ 50.f, 50.f},
|
|
|
|
{100.f, 100.f}});
|
|
|
|
|
|
|
|
// Through the centre
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b2.intersections ({100.f, 0.f}, {0.f, 100.f}), 1u, "intersect bezier-2 centre");
|
|
|
|
tap.expect_eq (b2.intersections ({0.f, 100.f}, {100.f, 0.f}), 1u, "intersect bezier-2 centre");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Coincident with endpoints
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b2.intersections ({0.f, 0.f}, {0.f,100.f}), 1u, "intersect bezier-2 endpoint");
|
|
|
|
tap.expect_eq (b2.intersections ({0.f, 0.f}, {100.f,0.f}), 1u, "intersect bezier-2 endpoint");
|
|
|
|
tap.expect_eq (b2.intersections ({100.f, 100.f}, {100.f,0.f}), 1u, "intersect bezier-2 endpoint");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Co-planar
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b2.intersections ({0.f, 0.f}, {1.f, 1.f}), 1u, "intersect bezier-2 co-planar");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Underneath
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b2.intersections ({1000.f, -10.f}, {-1000.f, -10.f}), 0u, "intersect bezier-2 under");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Above
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b2.intersections ({1000.f, 110.f}, {-1000.f, 110.f}), 0u, "intersect bezier-2 above");
|
2015-01-29 15:47:40 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_intersect<3> (cruft::TAP::logger &tap)
|
2015-01-29 15:47:40 +11:00
|
|
|
{
|
|
|
|
// A linear curve from (0,0) to (100,100)
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<3> b3 ({{ 0.f, 0.f },
|
2015-01-29 15:47:40 +11:00
|
|
|
{ 33.f, 33.f },
|
|
|
|
{ 67.f, 67.f },
|
|
|
|
{ 100.f, 100.f }});
|
|
|
|
|
|
|
|
// Through the centre
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b3.intersections ({100.f, 0.f}, {0.f, 100.f}), 1u, "intersect bezier-3 centre");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Coincident with endpoints
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b3.intersections ({0.f, 0.f}, {0.f,100.f}), 1u, "intersect bezier-3 endpoint");
|
|
|
|
tap.expect_eq (b3.intersections ({0.f, 0.f}, {100.f,0.f}), 1u, "intersect bezier-3 endpoint");
|
|
|
|
tap.expect_eq (b3.intersections ({100.f, 100.f}, {100.f,0.f}), 1u, "intersect bezier-3 endpoint");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Co-planar
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b3.intersections ({0.f, 0.f}, {1.f, 1.f}), 1u, "intersect bezier-3 co-planar");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Underneath
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b3.intersections ({1000.f, -10.f}, {-1000.f, -10.f}), 0u, "intersect bezier-3 under");
|
2015-01-29 15:47:40 +11:00
|
|
|
|
|
|
|
// Above
|
2015-11-13 17:10:10 +11:00
|
|
|
tap.expect_eq (b3.intersections ({1000.f, 110.f}, {-1000.f, 110.f}), 0u, "intersect bezier-3 above");
|
2015-01-29 15:47:40 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-03 12:53:41 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_region<1> (cruft::TAP::logger &tap)
|
2015-02-03 12:53:41 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::point2f p0 { 0, 0 },
|
2018-03-15 13:37:18 +11:00
|
|
|
// p1 { 100, 0 },
|
2015-03-06 01:09:37 +11:00
|
|
|
p2 { 100, 100 },
|
|
|
|
p3 { 0, 100 };
|
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<1> upright ({p0, p2});
|
|
|
|
static const cruft::bezier<1> downleft ({p2, p0});
|
|
|
|
static const cruft::bezier<1> vertical ({p0, p3});
|
|
|
|
static const cruft::bezier<1> horizontal ({p0, p2});
|
2015-03-06 01:09:37 +11:00
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
tap.expect_eq (upright.region (), cruft::region2f (p0, p2), "bezier-1 region");
|
|
|
|
tap.expect_eq (downleft.region (), cruft::region2f (p0, p2), "bezier-1 region");
|
|
|
|
tap.expect_eq (vertical.region (), cruft::region2f (p0, p3), "bezier-1 region");
|
|
|
|
tap.expect_eq (horizontal.region (), cruft::region2f (p0, p2), "bezier-1 region");
|
2015-02-03 12:53:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_region<2> (cruft::TAP::logger &tap)
|
2015-02-03 12:53:41 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::point2f p0 { 0, 0 },
|
2015-03-06 01:09:37 +11:00
|
|
|
p1 { 50, 50 },
|
|
|
|
p2 { 100, 100 };
|
2015-02-03 12:53:41 +11:00
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<2> upright({p0, p1, p2});
|
2015-03-06 01:09:37 +11:00
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
tap.expect_eq (upright.region (), cruft::region2f (p0, p2), "bezier-2 region");
|
2015-02-03 12:53:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
template <>
|
|
|
|
void
|
2018-08-05 14:42:02 +10:00
|
|
|
test_region<3> (cruft::TAP::logger &tap)
|
2015-02-03 12:53:41 +11:00
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::point2f p0 { 0, 0 },
|
2015-03-06 01:09:37 +11:00
|
|
|
p1 { 33, 33 },
|
|
|
|
p2 { 67, 67 },
|
|
|
|
p3 { 100, 100 };
|
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
static const cruft::bezier<3> upright({p0, p1, p2, p3});
|
2015-02-03 12:53:41 +11:00
|
|
|
|
2018-08-05 14:42:02 +10:00
|
|
|
tap.expect_eq (upright.region (), cruft::region2f (p0, p3), "bezier-3 region");
|
2015-02-03 12:53:41 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-01-29 15:47:40 +11:00
|
|
|
//-----------------------------------------------------------------------------
|
2015-01-22 14:57:57 +11:00
|
|
|
int
|
|
|
|
main (int, char**)
|
|
|
|
{
|
2018-08-05 14:42:02 +10:00
|
|
|
cruft::TAP::logger tap;
|
2015-04-13 16:45:56 +10:00
|
|
|
|
|
|
|
test_eval<1> (tap);
|
|
|
|
test_eval<2> (tap);
|
|
|
|
test_eval<3> (tap);
|
2015-01-29 15:47:40 +11:00
|
|
|
|
2015-04-13 16:45:56 +10:00
|
|
|
test_intersect<1> (tap);
|
|
|
|
test_intersect<2> (tap);
|
|
|
|
test_intersect<3> (tap);
|
2015-01-22 14:57:57 +11:00
|
|
|
|
2015-04-13 16:45:56 +10:00
|
|
|
test_region<1> (tap);
|
|
|
|
test_region<2> (tap);
|
|
|
|
test_region<3> (tap);
|
2015-02-03 12:53:41 +11:00
|
|
|
|
2017-05-22 13:55:21 +10:00
|
|
|
return tap.status ();
|
2015-01-22 14:57:57 +11:00
|
|
|
}
|