Simple bezier curve
Posted: Mon Apr 03, 2017 10:12 pm
This script will create a body with a line shape, with vertices along a bezier curve. The control points for the curve will be the currently selected vertices. In theory you can use vertices of multiple different fixtures, but to make sure the ordering of vertices is what you intended, the best way is to make a dummy fixture to define the control points.
You can use any number of points (>=3) to make a curve, but I find that it gets harder to define the outcome you want as more points are added.
Another example:
The body location will be 0,0
Code: Select all
vec2 getBezierPoint( vec2[] points, int numPoints, float t ) {
vec2[] tmp = points;
int i = numPoints - 1;
while (i > 0) {
for (int k = 0; k < i; k++)
tmp[k] = tmp[k] + t * ( tmp[k+1] - tmp[k] );
i--;
}
vec2 answer = tmp[0];
return tmp[0];
}
void main() {
vertex[] verts = sv();
if ( verts.length < 3 ) {
print( "Need at least 3 vertices selected to make a bezier curve." );
return;
}
float numPoints = queryNumericValue("How many points?", 20);
vec2[] vs;
for (uint i = 0; i < verts.length; i++)
vs.insertLast( verts[i].wpos );
body b = addBody(-1, '{"type":"dynamic","awake":true}');
fixture f = b.addFixture(-1,
'{"density":1,"shapes":[{"radius":0,"type":"line"}],"friction":0.2,"vertices":{"x":[-0.5,0.5],"y":[0,0]}}}');
float increment = 1 / numPoints;
vec2[] points;
for (int i = 0; i < numPoints + 1; i++) {
float t = i * increment;
if ( t > 1 )
t = 1;
vec2 p = getBezierPoint( vs, vs.length, t );
if ( i < 2 )
f.setVertex( i, p );
else
f.addVertex( 999999, p );
}
}