Jump to content


Photo

bezier_curve scripts (update 3-20-11)


  • Please log in to reply
6 replies to this topic

#1 jsorgeagames

jsorgeagames

    GMC Member

  • GMC Member
  • 710 posts
  • Version:GM:Studio

Posted 12 March 2011 - 07:47 PM

bezier_curve_draw
This script draws bezier curves given an x, y, ds_list, and precision. The ds_list should be structured like [x0, y0, x1, y1, ...] and the script will draw multiple curves if there are more than four coordinates specified.

//bezier_curve_draw(x,y,list,prec);
//by jsorgeagames
var i, c, t, x0, y0, x1, y1, x2, y2, x3, y3, xx, yy;
draw_primitive_begin(pr_linestrip);
i = 0;
c = 0;
while(i < ds_list_size(argument2))
{
    c = i-2;
    if i == 0
        c = i;
    x0 = ds_list_find_value(argument2,c);
    y0 = ds_list_find_value(argument2,c+1);
    x1 = ds_list_find_value(argument2,c+2);
    y1 = ds_list_find_value(argument2,c+3);
    x2 = ds_list_find_value(argument2,c+4);
    y2 = ds_list_find_value(argument2,c+5);
    x3 = ds_list_find_value(argument2,c+6);
    y3 = ds_list_find_value(argument2,c+7);
    //cubic
    if c+7 < ds_list_size(argument2)
    {
        cx = 3*(x1-x0);
        cy = 3*(y1-y0);
        bx = 3*(x2-x1)-cx;
        by = 3*(y2-y1)-cy;
        ax = x3-x0-cx-bx;
        ay = y3-y0-cy-by;
        t = 0;
        for(t = 0; t <= 1; t += 1/argument3)
        {
            xx = argument0+ax*power(t,3)+bx*sqr(t)+cx*t+x0;
            yy = argument1+ay*power(t,3)+by*sqr(t)+cy*t+y0;
            draw_vertex(xx,yy);
        }
    }
    //quadratic
    if c+6 == ds_list_size(argument2)
    {
        t = 0;
        for(t = 0; t <= 1; t += 1/argument3)
        {
            ax = sqr(1-t);
            bx = 2*(1-t)*t;
            cx = sqr(t);
            xx = ax*x0+bx*x1+cx*x2;
            yy = ax*y0+bx*y1+cx*y2;
            draw_vertex(xx,yy);
        }
    }
    //linear
    if c+4 == ds_list_size(argument2)
    {
        draw_vertex(x0,y0);
        draw_vertex(x1,y1);
    }
    if i == 0
        i += 8;
    else
        i += 6;
}
draw_primitive_end();
bezier_curve_find_point
This script finds the point along a bezier curve given a ds_list, a curve id, and the position along the curve from 0 to 1 (t). The curve id is the index in the ds_list of the first coordinate of the curve.

//bezier_curve_find_point(list,listpos,t);
//by jsorgeagames
var c, t, x0, y0, x1, y1, x2, y2, x3, y3;
c = argument1;
t = argument2;
x0 = ds_list_find_value(argument0,c);
y0 = ds_list_find_value(argument0,c+1);
x1 = ds_list_find_value(argument0,c+2);
y1 = ds_list_find_value(argument0,c+3);
x2 = ds_list_find_value(argument0,c+4);
y2 = ds_list_find_value(argument0,c+5);
x3 = ds_list_find_value(argument0,c+6);
y3 = ds_list_find_value(argument0,c+7);
//cubic
if c+7 < ds_list_size(argument0)
{
    cx = 3*(x1-x0);
    cy = 3*(y1-y0);
    bx = 3*(x2-x1)-cx;
    by = 3*(y2-y1)-cy;
    ax = x3-x0-cx-bx;
    ay = y3-y0-cy-by;
    bcurve_x = ax*power(t,3)+bx*sqr(t)+cx*t+x0;
    bcurve_y = ay*power(t,3)+by*sqr(t)+cy*t+y0;
    exit;
}
//quadratic
if c+6 == ds_list_size(argument0)
{
    ax = sqr(1-t);
    bx = 2*(1-t)*t;
    cx = sqr(t);
    bcurve_x = ax*x0+bx*x1+cx*x2;
    bcurve_y = ax*y0+bx*y1+cx*y2;
    exit;
}
//linear
bcurve_x = x0+t*(x1-x0);
bcurve_y = y0+t*(y1-y0);
Screenshots:
Posted Image
[ 1 ] [ 2 ]

Example:
beziercurves.gmk 11.5 kb

Edited by jsorgeagames, 24 March 2011 - 04:08 PM.

  • 1

#2 johnjoe

johnjoe

    GMC Member

  • New Member
  • 299 posts
  • Version:Unknown

Posted 12 March 2011 - 07:55 PM

can you modify the example in use with movements?
  • 0

#3 jsorgeagames

jsorgeagames

    GMC Member

  • GMC Member
  • 710 posts
  • Version:GM:Studio

Posted 12 March 2011 - 10:10 PM

can you modify the example in use with movements?

If you mean dragging the points in the example in real-time, then yes.
  • 0

#4 johnjoe

johnjoe

    GMC Member

  • New Member
  • 299 posts
  • Version:Unknown

Posted 13 March 2011 - 03:08 AM

that's fancy, yea sure.

i mean, an object that follows the array of bezier primitive line coordinates. the object to follow the curve.
  • 0

#5 Davve

Davve

    GMC Member

  • GMC Member
  • 4091 posts
  • Version:GM:Studio

Posted 15 March 2011 - 12:09 PM

Nice, but it should allow an infinite number of points, using something like draw_bezier_curve(list,prec), where list is the ID of a ds_list containing all the coordinates (1st item is x1, 2nd item is y1, 3rd item is x2 and so fourth).
  • 0

#6 jsorgeagames

jsorgeagames

    GMC Member

  • GMC Member
  • 710 posts
  • Version:GM:Studio

Posted 16 March 2011 - 06:27 PM

i mean, an object that follows the array of bezier primitive line coordinates. the object to follow the curve.

You can easily add this in yourself, just copy the code and set i to a value from 0 to 1 (it's a percentage along the curve). I'll probably update the example soon with a faster version of the script and this included though.

Nice, but it should allow an infinite number of points, using something like draw_bezier_curve(list,prec), where list is the ID of a ds_list containing all the coordinates (1st item is x1, 2nd item is y1, 3rd item is x2 and so fourth).

I'll add this in as well by combining low-order curves (the cubic curves in the example) together.

Edited by jsorgeagames, 16 March 2011 - 06:28 PM.

  • 0

#7 jsorgeagames

jsorgeagames

    GMC Member

  • GMC Member
  • 710 posts
  • Version:GM:Studio

Posted 20 March 2011 - 09:14 PM

I updated the post - there are now two scripts, one for drawing and one for finding the [x,y] of position t (0-1) on a curve. The drawing script now uses a ds_list for drawing.

Edited by jsorgeagames, 20 March 2011 - 09:15 PM.

  • 0