Added BezierCurve:renderSegment

This commit is contained in:
muddmaker
2014-09-30 17:36:10 -07:00
parent d3e1993673
commit 238656ecc1
5 changed files with 68 additions and 0 deletions
+34
View File
@@ -183,6 +183,40 @@ vector<Vector> BezierCurve::render(size_t accuracy) const
return vertices;
}
vector<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<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
+9
View File
@@ -113,6 +113,15 @@ public:
* @returns A polygon chain that approximates the bezier curve.
**/
std::vector<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<Vector> renderSegment(double start, double end, size_t accuracy = 4) const;
private:
std::vector<Vector> controlPoints;
+23
View File
@@ -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<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 }
};
+1
View File
@@ -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