From 238656ecc163a1c608e05c45d2a1f2e9f7d88977 Mon Sep 17 00:00:00 2001 From: muddmaker Date: Tue, 30 Sep 2014 17:36:10 -0700 Subject: [PATCH] Added BezierCurve:renderSegment --- changes.txt | 1 + src/modules/math/BezierCurve.cpp | 34 +++++++++++++++++++++++++++ src/modules/math/BezierCurve.h | 9 +++++++ src/modules/math/wrap_BezierCurve.cpp | 23 ++++++++++++++++++ src/modules/math/wrap_BezierCurve.h | 1 + 5 files changed, 68 insertions(+) diff --git a/changes.txt b/changes.txt index 41704b360..06a651fea 100644 --- a/changes.txt +++ b/changes.txt @@ -23,6 +23,7 @@ LOVE 0.9.2 [Baby Inspector] * Added love.window.toPixels and love.window.fromPixels. * Added love.window.setPosition and love.window.getPosition, and 'x' and 'y' fields to love.window.setMode and t.window in love.conf. * Added love.filesystem.isSymlink, love.filesystem.setSymlinksEnabled, and love.filesystem.areSymlinksEnabled. + * Added BezierCurve:renderSegment. * Deprecated SpriteBatch:bind and SpriteBatch:unbind. * Deprecated all uses of the name 'FSAA' in favor of 'MSAA'. diff --git a/src/modules/math/BezierCurve.cpp b/src/modules/math/BezierCurve.cpp index 33c96c56f..7ceac9e7e 100644 --- a/src/modules/math/BezierCurve.cpp +++ b/src/modules/math/BezierCurve.cpp @@ -183,6 +183,40 @@ vector BezierCurve::render(size_t accuracy) const return vertices; } +vector BezierCurve::renderSegment(double start, double end, size_t accuracy) const +{ + if (controlPoints.size() < 2) + throw Exception("Invalid Bezier curve: Not enough control points."); + vector vertices(controlPoints); + subdivide(vertices, accuracy); + if (start > 0) + { + Vector startPoint = evaluate(start); + for (size_t i = 0; i < vertices.size(); ++i) + { + if ((double)i / vertices.size() > start) + { + vertices.erase(vertices.begin(), vertices.begin() + i - 1); + break; + } + } + vertices.insert(vertices.begin(), startPoint); + } + if (end < 1) + { + Vector endPoint = evaluate(end); + for (size_t i = vertices.size(); i > 0; --i) + { + if ((double)(i - 1) / vertices.size() < end) + { + vertices.erase(vertices.begin() + i, vertices.end()); + break; + } + } + vertices.insert(vertices.end(), endPoint); + } + return vertices; +} } // namespace math } // namespace love diff --git a/src/modules/math/BezierCurve.h b/src/modules/math/BezierCurve.h index 9370dc52f..e35e45c08 100644 --- a/src/modules/math/BezierCurve.h +++ b/src/modules/math/BezierCurve.h @@ -113,6 +113,15 @@ public: * @returns A polygon chain that approximates the bezier curve. **/ std::vector render(size_t accuracy = 4) const; + + /** + * Renders a segment of the curve by subdivision. + * @param start The starting point (between 0 and 1) on the curve. + * @param end The ending point on the curve. + * @param accuracy The 'fineness' of the curve. + * @returns A polygon chain that approximates the segment along the curve + **/ + std::vector renderSegment(double start, double end, size_t accuracy = 4) const; private: std::vector controlPoints; diff --git a/src/modules/math/wrap_BezierCurve.cpp b/src/modules/math/wrap_BezierCurve.cpp index 659c0bd7f..b49b4f231 100644 --- a/src/modules/math/wrap_BezierCurve.cpp +++ b/src/modules/math/wrap_BezierCurve.cpp @@ -165,6 +165,28 @@ int w_BezierCurve_render(lua_State *L) return 1; } +int w_BezierCurve_renderSegment(lua_State *L) +{ + BezierCurve *curve = luax_checkbeziercurve(L, 1); + double start = luaL_checknumber(L, 2); + double end = luaL_checknumber(L, 3); + int accuracy = luaL_optinteger(L, 4, 5); + + std::vector points; + luax_catchexcept(L, [&](){ points = curve->renderSegment(start, end, accuracy); }); + + lua_createtable(L, points.size()*2, 0); + for (size_t i = 0; i < points.size(); ++i) + { + lua_pushnumber(L, points[i].x); + lua_rawseti(L, -2, 2*i+2); + lua_pushnumber(L, points[i].y); + lua_rawseti(L, -2, 2*i+2); + } + + return 1; +} + static const luaL_Reg functions[] = { {"getDegree", w_BezierCurve_getDegree}, @@ -178,6 +200,7 @@ static const luaL_Reg functions[] = {"scale", w_BezierCurve_scale}, {"evaluate", w_BezierCurve_evaluate}, {"render", w_BezierCurve_render}, + {"renderSegment", w_BezierCurve_renderSegment}, { 0, 0 } }; diff --git a/src/modules/math/wrap_BezierCurve.h b/src/modules/math/wrap_BezierCurve.h index ad0558e96..9eb6fb9bf 100644 --- a/src/modules/math/wrap_BezierCurve.h +++ b/src/modules/math/wrap_BezierCurve.h @@ -42,6 +42,7 @@ int w_BezierCurve_rotate(lua_State *L); int w_BezierCurve_scale(lua_State *L); int w_BezierCurve_evaluate(lua_State *L); int w_BezierCurve_render(lua_State *L); +int w_BezierCurve_renderSegment(lua_State *L); extern "C" int luaopen_beziercurve(lua_State *L); } // math