From 20b3adbc558a80f0d6ae7b396ef5305f22975f88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Mon, 12 Dec 2016 19:45:16 +0100 Subject: [PATCH] Math: ability to convert Bezier from/to external representation. --- src/Magnum/Math/Bezier.h | 12 +++++++++ src/Magnum/Math/Test/BezierTest.cpp | 42 ++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/Magnum/Math/Bezier.h b/src/Magnum/Math/Bezier.h index a40051769..ab8be57e6 100644 --- a/src/Magnum/Math/Bezier.h +++ b/src/Magnum/Math/Bezier.h @@ -36,6 +36,10 @@ namespace Magnum { namespace Math { +namespace Implementation { + template struct BezierConverter; +} + /** @brief Bézier curve @tparam order Order of Bézier curve @@ -95,6 +99,14 @@ template class Bezier { */ template constexpr explicit Bezier(const Bezier& other) noexcept: Bezier{typename Implementation::GenerateSequence::Type(), other} {} + /** @brief Construct Bézier from external representation */ + template::from(std::declval()))> constexpr explicit Bezier(const U& other) noexcept: Bezier{Implementation::BezierConverter::from(other)} {} + + /** @brief Convert Bézier to external representation */ + template::to(std::declval>()))> constexpr explicit operator U() const { + return Implementation::BezierConverter::to(*this); + } + /** @brief Equality comparison */ bool operator==(const Bezier& other) const { for(std::size_t i = 0; i != order + 1; ++i) diff --git a/src/Magnum/Math/Test/BezierTest.cpp b/src/Magnum/Math/Test/BezierTest.cpp index ae84e965f..141153189 100644 --- a/src/Magnum/Math/Test/BezierTest.cpp +++ b/src/Magnum/Math/Test/BezierTest.cpp @@ -32,7 +32,27 @@ #include "Magnum/Math/Vector2.h" #include "Magnum/Math/Functions.h" -namespace Magnum { namespace Math { namespace Test { +struct QBezier2D { + float x0, x1, x2, y0, y1, y2; +}; + +namespace Magnum { namespace Math { + +namespace Implementation { + +template<> struct BezierConverter<2, 2, Float, QBezier2D> { + constexpr static QuadraticBezier2D from(const QBezier2D& other) { + return {Vector2{other.x0, other.y0}, Vector2{other.x1, other.y1}, Vector2{other.x2, other.y2}}; + } + + constexpr static QBezier2D to(const QuadraticBezier2D& other) { + return {other[0][0], other[1][0], other[2][0], other[0][1], other[1][1], other[2][1]}; + } +}; + +} + +namespace Test { typedef Math::Vector2 Vector2; typedef Math::Vector2 Vector2d; @@ -49,6 +69,7 @@ struct BezierTest : Corrade::TestSuite::Tester { void constructNoInit(); void constructConversion(); void constructCopy(); + void convert(); void data(); @@ -71,6 +92,7 @@ BezierTest::BezierTest() { &BezierTest::constructNoInit, &BezierTest::constructConversion, &BezierTest::constructCopy, + &BezierTest::convert, &BezierTest::data, @@ -142,6 +164,24 @@ void BezierTest::constructCopy() { CORRADE_VERIFY(std::is_nothrow_copy_assignable::value); } +void BezierTest::convert() { + constexpr QBezier2D a{0.5f, 1.1f, 0.1f, 1.0f, 0.3f, 1.2f}; + constexpr QuadraticBezier2D b{Vector2{0.5f, 1.0f}, Vector2{1.1f, 0.3f}, Vector2{0.1f, 1.2f}}; + + constexpr QuadraticBezier2D c{a}; + CORRADE_COMPARE(c, b); + + constexpr QBezier2D d(b); + CORRADE_COMPARE(d.x0, a.x0); + CORRADE_COMPARE(d.x1, a.x1); + CORRADE_COMPARE(d.y0, a.y0); + CORRADE_COMPARE(d.y1, a.y1); + + /* Implicit conversion is not allowed */ + CORRADE_VERIFY(!(std::is_convertible::value)); + CORRADE_VERIFY(!(std::is_convertible::value)); +} + void BezierTest::data() { QuadraticBezier2D a{Vector2{0.5f, 1.0f}, Vector2{1.1f, 0.3f}, Vector2{0.1f, 1.2f}}; a[0] = {};