Page 1 of 1

Simple bezier curve

Posted: Mon Apr 03, 2017 10:12 pm
by iforce2d
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.
Selection_010.png
Selection_010.png (5.15 KiB) Viewed 26360 times
Selection_011.png
Selection_011.png (9.81 KiB) Viewed 26360 times
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.
Selection_012.png
Selection_012.png (9.19 KiB) Viewed 26360 times
Another example:
Selection_013.png
Selection_013.png (5.61 KiB) Viewed 26360 times
Selection_014.png
Selection_014.png (7.76 KiB) Viewed 26360 times
Selection_015.png
Selection_015.png (9.19 KiB) Viewed 26360 times
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 );

    }
}

Re: Simple bezier curve

Posted: Wed Dec 13, 2017 10:39 pm
by Nathan
Hi,

I've been using this script to create my levels for my game. However, I'd ideally like to randomly generate a chain shape with 4 vertices and create a bezier curve with them (like you do here). Once that's done, append it with another randomly generated 4 vertice shape and so on. So I can hit run and generate a random track in seconds.

I'm having a lot of trouble with Angelscript though. Not relying on all the helpers an IDE like Android Studio gives + the unfamiliar methods. Where does the method sv come from? vertex[] verts = sv(); I have no idea where to look :S
The only programming language I know atm is Java. Do I need to learn some basic C/C++ before moving to Angelscript? How would you recommend learning it? I'm not sure if it's worth learning it or not.

Thanks!

Re: Simple bezier curve

Posted: Thu Dec 14, 2017 1:08 am
by iforce2d
Most of the functions will be RUBE specific, they are not part of Angelscript itself. There is a full reference of all RUBE functions in the built-in help. Some of the very commonly used functions have a shorter version just to save a little time when whipping up a quick one-off script. The sv() function is short-hand for getSelectedVertices.

If you are doing a lot of work with vertices, see these topics in the built-in help:
Rubescript reference -> Global functions -> RUBE global functions -> Vertex related
Rubescript reference -> RUBE item classes -> vertex

For random number generation, see the rnd and srand functions here:
Rubescript reference -> Global functions -> Math functions -> Other

If you will be re-using your script a lot you may also be interested in adding it to the main action menu:
https://www.youtube.com/watch?v=ZVmBrebebEY

You can also trigger scripts via a keypress, as explained in the 1.4 update video:
https://youtu.be/XM_yYvk3AKk?t=15m58s

Re: Simple bezier curve

Posted: Fri Dec 15, 2017 11:03 pm
by Nathan
Thanks a ton for this info. I don't know why I didn't check the rube help section, I just assumed it was all part of the default angelscript library.
You know, it would be really useful if the rube help pages were on your website. It would mean I could read through them while at work (while on my break ;) )

Re: Simple bezier curve

Posted: Sat Dec 16, 2017 1:04 am
by iforce2d
They are, http://www.iforce2d.net/rubehelp

The link is given on the main intro page of the built-in help if you need to find it again.

Re: Simple bezier curve

Posted: Sat Dec 16, 2017 2:12 pm
by Nathan
Cheers :D