[BezierCurve] Add getDerivative(), move(), rotate() and scale().

This commit is contained in:
vrld
2013-08-21 21:44:31 +02:00
parent aa53712278
commit 983496238f
4 changed files with 109 additions and 1 deletions
+39 -1
View File
@@ -22,7 +22,7 @@
#include "BezierCurve.h"
#include "common/Exception.h"
#include <iostream>
#include <cmath>
using namespace std;
@@ -87,6 +87,21 @@ BezierCurve::BezierCurve(const vector<Vector> &pts)
{
}
BezierCurve BezierCurve::getDerivative() const
{
if (getDegree() < 1)
throw Exception("Cannot derive a curve of degree < 1.");
// actually we can, it just doesn't make any sense.
vector<Vector> forward_differences(controlPoints.size()-1);
float degree = float(getDegree());
for (size_t i = 0; i < forward_differences.size(); ++i)
forward_differences[i] = (controlPoints[i+1] - controlPoints[i]) * degree;
return BezierCurve(forward_differences);
}
const Vector &BezierCurve::getControlPoint(int i) const
{
if (i < 0)
@@ -120,6 +135,29 @@ void BezierCurve::insertControlPoint(const Vector &point, int pos)
controlPoints.insert(controlPoints.begin() + pos, point);
}
void BezierCurve::translate(const Vector &t)
{
for (size_t i = 0; i < controlPoints.size(); ++i)
controlPoints[i] += t;
}
void BezierCurve::rotate(double phi, const Vector &center)
{
float c = cos(phi), s = sin(phi);
for (size_t i = 0; i < controlPoints.size(); ++i)
{
Vector v = controlPoints[i] - center;
controlPoints[i].x = c * v.x - s * v.y + center.x;
controlPoints[i].y = s * v.x + c * v.y + center.y;
}
}
void BezierCurve::scale(double s, const Vector &center)
{
for (size_t i = 0; i < controlPoints.size(); ++i)
controlPoints[i] = (controlPoints[i] - center) * s + center;
}
Vector BezierCurve::eval(double t) const
{
if (t < 0 || t > 1)
+25
View File
@@ -48,6 +48,11 @@ public:
return controlPoints.size() - 1;
}
/**
* @returns First derivative of the curve.
*/
BezierCurve getDerivative() const;
/**
* @returns i'th control point.
**/
@@ -68,6 +73,26 @@ public:
**/
void insertControlPoint(const Vector &point, int pos = -1);
/**
* Move the curve.
* @param t Translation vector.
*/
void translate(const Vector &t);
/**
* Rotate the curve.
* @param phi Rotation angle (radians).
* @param center Rotation center.
*/
void rotate(double phi, const Vector &center);
/**
* Scale the curve.
* @param s Scale factor.
* @param center Scale center.
*/
void scale(double phi, const Vector &center);
/**
* Evaluates the curve at time t.
* @param t Curve parameter, must satisfy 0 <= t <= 1.
+41
View File
@@ -40,6 +40,14 @@ int w_BezierCurve_getDegree(lua_State *L)
return 1;
}
int w_BezierCurve_getDerivative(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
BezierCurve *deriv = new BezierCurve(curve->getDerivative());
luax_newtype(L, "BezierCurve", MATH_BEZIER_CURVE_T, (void *)deriv);
return 1;
}
int w_BezierCurve_getControlPoint(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
@@ -106,6 +114,35 @@ int w_BezierCurve_insertControlPoint(lua_State *L)
return 0;
}
int w_BezierCurve_move(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
double dx = luaL_checknumber(L, 2);
double dy = luaL_checknumber(L, 3);
curve->translate(Vector(dx,dy));
return 0;
}
int w_BezierCurve_rotate(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
double phi = luaL_checknumber(L, 2);
double ox = luaL_optnumber(L, 3, 0);
double oy = luaL_optnumber(L, 4, 0);
curve->rotate(phi, Vector(ox,oy));
return 0;
}
int w_BezierCurve_scale(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
double s = luaL_checknumber(L, 2);
double ox = luaL_optnumber(L, 3, 0);
double oy = luaL_optnumber(L, 4, 0);
curve->scale(s, Vector(ox,oy));
return 0;
}
int w_BezierCurve_eval(lua_State *L)
{
BezierCurve *curve = luax_checkbeziercurve(L, 1);
@@ -148,9 +185,13 @@ int w_BezierCurve_render(lua_State *L)
static const luaL_Reg functions[] =
{
{"getDegree", w_BezierCurve_getDegree},
{"getDerivative", w_BezierCurve_getDerivative},
{"getControlPoint", w_BezierCurve_getControlPoint},
{"setControlPoint", w_BezierCurve_setControlPoint},
{"insertControlPoint", w_BezierCurve_insertControlPoint},
{"move", w_BezierCurve_move},
{"rotate", w_BezierCurve_rotate},
{"scale", w_BezierCurve_scale},
{"eval", w_BezierCurve_eval},
{"render", w_BezierCurve_render},
{ 0, 0 }
+4
View File
@@ -32,9 +32,13 @@ namespace math
BezierCurve *luax_checkbeziercurve(lua_State *L, int idx);
int w_BezierCurve_getDegree(lua_State *L);
int w_BezierCurve_getDerivative(lua_State *L);
int w_BezierCurve_getControlPoint(lua_State *L);
int w_BezierCurve_setControlPoint(lua_State *L);
int w_BezierCurve_insertControlPoint(lua_State *L);
int w_BezierCurve_move(lua_State *L);
int w_BezierCurve_rotate(lua_State *L);
int w_BezierCurve_scale(lua_State *L);
int w_BezierCurve_eval(lua_State *L);
int w_BezierCurve_render(lua_State *L);
extern "C" int luaopen_beziercurve(lua_State *L);