Simple bezier curve

Let us know if you have a nice R.U.B.E script to share!
Post Reply
iforce2d
Site Admin
Posts: 855
Joined: Sat Dec 22, 2012 7:20 pm

Simple bezier curve

Post by iforce2d » 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.
Selection_010.png
Selection_010.png (5.15 KiB) Viewed 6407 times
Selection_011.png
Selection_011.png (9.81 KiB) Viewed 6407 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 6407 times
Another example:
Selection_013.png
Selection_013.png (5.61 KiB) Viewed 6407 times
Selection_014.png
Selection_014.png (7.76 KiB) Viewed 6407 times
Selection_015.png
Selection_015.png (9.19 KiB) Viewed 6407 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 );

    }
}

Nathan
Posts: 8
Joined: Sun Aug 28, 2016 10:13 pm

Re: Simple bezier curve

Post by Nathan » Wed Dec 13, 2017 10:39 pm

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!

iforce2d
Site Admin
Posts: 855
Joined: Sat Dec 22, 2012 7:20 pm

Re: Simple bezier curve

Post by iforce2d » Thu Dec 14, 2017 1:08 am

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

Nathan
Posts: 8
Joined: Sun Aug 28, 2016 10:13 pm

Re: Simple bezier curve

Post by Nathan » Fri Dec 15, 2017 11:03 pm

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 ;) )

iforce2d
Site Admin
Posts: 855
Joined: Sat Dec 22, 2012 7:20 pm

Re: Simple bezier curve

Post by iforce2d » Sat Dec 16, 2017 1:04 am

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.

Nathan
Posts: 8
Joined: Sun Aug 28, 2016 10:13 pm

Re: Simple bezier curve

Post by Nathan » Sat Dec 16, 2017 2:12 pm

Cheers :D

Post Reply