GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2009-12-01 01:55:10

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

bezier4

Computes a cubic Bézier curve given a parameter, t, and four control points, {p0,p1,p2,p3}.

[tex]\mathbf{B}(t)=(1-t)^3\mathbf{P}_0+3(1-t)^2t\mathbf{P}_1+3(1-t)t^2\mathbf{P}_2+t^3\mathbf{P}_3 \mbox{ , } t \in [0,1].[/tex]

//  bezier4(t,p0,p1,p2,p3)
{
    argument5 = 1 - argument0;
    return 
    power(argument5,3)                 * argument1 +
    power(argument5,2) * 3 * argument0 * argument2 +
    power(argument0,2) * 3 * argument5 * argument3 + 
    power(argument0,3)                 * argument4;
}

Can this be optimized?


Abusing forum power since 1986.

Offline

#2 2009-12-01 22:55:41

RaiSoleil
Member
Registered: 2009-08-02
Posts: 16

Re: bezier4

Depends. If you're calculating a series of points on one curve, you can precalculate some important stuff and use a different equation to save time.

Pseudocode, off the top of my head:

a = P3 - 3(P2 - P1) - P0
b = 3(P2 - 2P1 + P0)
c = 3(P1 - P0)

And then for any t on the the cubic curve B:

B(t) = ((a*t + b)*t + c)*t + P0

You should be able to confirm a, b, and c by multiplying out the equation you have above and then regrouping by powers of t instead of by point #.

But I've got something even better. This script will work for an arbitrary number of points (just specify the right degree) and works on pure add/sub/mult/div. A cubic call takes 0.02 milliseconds.

/*
scr_bezier_point();

0 degree
1 t
n point
*/

var a, i, n, t, t1;

a = argument2;
i = 1;
n = 1;
t = 1;
t1 = 1-argument1;

repeat argument0 {
    n *= (argument0-i+1) / i;
    t *= argument1;
    a *= t1;
    a += argument[i+2] * n * t;
    i += 1;
    }
    
return a;

Bezier curves are crazy stuff. I came up with some equations for bezier-to-circle collision detection in April, and then this semester I wrote a paper on them to get credit for a calculus class. Booyah.

Offline

#3 2009-12-02 07:03:30

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: bezier4

I guess if GM was compiled and had static variables, the first optimization could be included for a little boost. It's certainly useful information for special cases. Maybe a function that returns a list of values might be in order since it could take advantage of the precomputation. And it would be just plain handy in many cases.

Your nth degree Bézier function is awesome. I had a vague notion that something like that would be possible after reading a bit about how the equation is structured. That's totally going on the site.

I've always found splines a bit mysterious because it's difficult for me to visualize the mathematics involved. Then I saw these animations on Wikipedia that made everything so much clearer.

DRlDu1c.gif

It sort of amused me as well. Some of my earliest graphics coding (circa 1982) used this same approach to drawing curves. All these years later and I had no idea it was related to how a Bézier curve actually works.

Gjl1Ru6.png


Abusing forum power since 1986.

Offline

#4 2009-12-02 19:31:04

icuurd12b42
Member
Registered: 2008-12-11
Posts: 303

Re: bezier4

These animations are new. They were not there a while back. Only a bunch of equations. I'm glad someone finally realise the usefulness of pictures.

Offline

#5 2009-12-03 00:51:45

xDanielx
Member
Registered: 2009-01-02
Posts: 38

Re: bezier4

xot wrote:

DRlDu1c.gif

That's just... not fair. Bézier curves shouldn't be that simple.

Offline

#6 2010-03-01 21:47:11

brac37
Member
Registered: 2010-02-12
Posts: 18

Re: bezier4

xot wrote:

Computes a cubic Bézier curve given a parameter, t, and four control points, {p0,p1,p2,p3}.

[tex]\mathbf{B}(t)=(1-t)^3\mathbf{P}_0+3(1-t)^2t\mathbf{P}_1+3(1-t)t^2\mathbf{P}_2+t^3\mathbf{P}_3 \mbox{ , } t \in [0,1].[/tex]

//  bezier4(t,p0,p1,p2,p3)
{
    argument5 = 1 - argument0;
    return 
    power(argument5,3)                 * argument1 +
    power(argument5,2) * 3 * argument0 * argument2 +
    power(argument0,2) * 3 * argument5 * argument3 + 
    power(argument0,3)                 * argument4;
}

Can this be optimized?

Well, one/two times multiplication is faster than second/third power, I would think. Further, the terms in the middle can be factorized.

//  bezier4(t,p0,p1,p2,p3)
{
    argument5 = 1 - argument0;
    return 
    sqr(argument5) * argument5 * argument1 +
    3 * argument0 * argument5 * (argument5 * 
    argument2 + argument0 * argument3) +
    sqr(argument0 * argument0 * argument4;
}

Offline

Board footer

Powered by FluxBB