The Ultrashock Ultra Bundle
  • Home
  • Community
  • Forum
  • Archived Forums
  • Sources & Experiments
  • Thread
  •  
  • Previous topic
  • Next topic
Sign up to post

Archived Forums
 Sources & Experiments

  • Codemonkey Author 
    • 6722 
    • 0 
    • 22 
    Fun with Bezier curves
    bleep

    Last reply Nov 08 2009, 09:34 AM

    by bleep

    Posted: Aug 23 2005, 01:30 PM

    by Codemonkey

     

I made this into a blog post here.
——————-

Here’s the list with all examples posted so far.


[list]
[*]Bezier controlpoint demonstration as1.0 lookup table and source
[*]JelloWave.html and source
[*]Globb_a.html and source
[*]Globb_b.html and source
[*]donut and source
[*]Globbor and source
[*]trailer.html and source
[*]wheeler.html and source
[*]sketcher.html and source
[*]Bezier3D.html and source
[/list]

For the other Bezier controlpoint demonstrations you can find them down this post (this one is the fastest implementation).

If you have any questions about any of these examples, about the actionscript or math,  let me know. I’ll gladly help. good

sketchersmall.png

———————
NOTE: the time measurements are pretty old, with player 9 for example *all* versions have become blasting fast. Still, the principle of a lookup table still apply to very heavy repetitive math duty.

Hi guys,

I was doing some personal research in Bezier curves and was interested in finding way to draw Bezier curves through a dynamic number of controlpoints. The problem was, everywhere I looked for some information it was always about Bezier curves up to 5 controlpoints, which were calculated with an optimized formula for exactly that amount of controlpoints (a simplified version of the general formula for n+1 controlpoints). So I wrote my own take on it; one that can handle an unlimited amount of controlpoints added dynamically, that still retains enough speed and also lets you control how smooth the curves are.

To get some background information on Bezier curves, quadratic and cubic curves, visit Bezier, cubic Bezier curves in flash and flash drawing methods. There are also some threads on Bezier curves here on Ultrashock, including one by Robert Penner.

——-

empty setup preview, source.fla
Here I go. Take a look at this fla. The only code in it is to create the draggable controlpoints and the empty drawBezierCurves function that is being called when a controlpoint has changed (because you dragged it, or added new ones). The buttons at the bottom reset the movie with a number of controlpoints, and the buttons below that change how smooth the line should be. The textfield in the upper right corner indicates how fast the Bezier curve was drawn. We’ll add more to this movie as we go along.

Now take a look at this Bezier formula.
bezierfomula.png

Converted into actionscript, this is

[as]
(factorial(N) / (factorial(k) * factorial(N - k))) * Math.pow(u, k) * Math.pow(1 - u, N - k);

// where factorial ‘!’ is our custom recursive function

function factorial(x:Number):Number {
return (x <= 1) ? 1 : x * factorial(x - 1);
}
[/as]
To actually calculate x and y, consider the following example, where we have 5 controlpoints, and thus N is 4 (the formula says N+1 controlpoints). The controlpoints are the movieclips that you can drag.

[as]
var stepsize:Number = 1/30;
var N:Number = 4;
for (var u = 0; u <= 1; u += stepsize) {
  x = y = 0;
  for (var k = 0; k <= N; k++) {
  var blend:Number = (factorial(N) / (factorial(k) * factorial(N - k))) *
Math.pow(u, k) * Math.pow(1 -  u, N - k);
  x += this[“controlPoint” + k]._x * blend;
  y += this[“controlPoint” + k]._y * blend;
  }
  this.lineTo(x, y);
}
[/as]
First of, u is the ‘lifetime’ variable of the Bezier curve. For example u = 1 is all the way to the end of the curve on the last controlpoint, u = 0 is at the beginning at the first controlpoint, and u = 0.5 is exactly in the middle of the line. The smaller the steps you take, the smoother the line is going to be, because you use smaller intervals. Also, the stepSize has to be at least as big as the number of controlpoints. Otherwise, the line won’t even reach the controlpoints on the end.

This is what the movie does with this code
example1, source.fla

Cool huh, this works for every N. Try it at 15 controlpoints in overkill mode; it now is doing (15 controlpoints * 6 smoothmodifier) steps * 15 = 1350 cycles of Bezier calculations on *each* update. See the speed at around 220ms in standalone player? As you can imagine, this is rather heavy duty for the cpu, as it has to do three factorials, two powers and some multiplications for every x,y point we calculate each cycle. That’s why most examples you find don’t use this method and use an formula that is optimized for (and limited to) up to 5 controlpoints. For example this document shows special cases for exactly 2 and 3 controlpoints. This greatly increases speed, but you are limited to 2 and 3 controlpoints. There is another way however to speed things up: Lookup tables.

For those who don’t know what lookup tables are; they are tables that have heavy-duty calculations done forehand so that you can later on just fetch the value instead of doing the calculation. I also wrote something about lookup tables here, that basically is an as2 class that automates the lookup tables for you. But for this example, I’ll keep it short and simple and stick to as1 timeline apple pie. First, we’ll create a lookup table for the factorial calculations.

[as]
var factorialTable:Array = new Array();

for (var k = 0; k <= N; k++) {
factorialTable[k] = factorial(k);
}
[/as]
You see, we only calculate the values that we’ll need for the Bezier curves. No more, no less. However, this means we have to update the lookup table every time we add or remove a controlpoint.

Now the lookup table for power.

[as]
var powerTable:Array = new Array();

for (var u = 0; u <= 1; u += stepsize) {
if (powerTable == undefined) {
  powerTable = new Array();
}
if (powerTable[1 - u] == undefined) {
  powerTable[1 - u] = new Array();
}
for (var k = 0; k <= N; k++) {
  powerTable[k] = Math.pow(u, k);
  powerTable[1 - u][k] = Math.pow(1 - u, k);
}
}
[/as]
Now, our method to calculate the Bezier curves looks like this:

[as]
var stepsize:Number = 1 / 30;
var N:Number = 4;

for (var u = 0; u <= 1; u += stepsize) {
x = y = 0;
for (var k = 0; k <= N; k++) {
  var blend:Number = (factorialTable[N] / (factorialTable[k] *
factorialTable[N - k])) * powerTable[k] *  powerTable[1 - u][N - k];
  x += this[“controlPoint” + k]._x * blend;
  y += this[“controlPoint” + k]._y * blend;
}
this.lineTo(x, y);
}
[/as]
I also made a version with a lookup table for the Bezier blend values instead of power and factorial values. Here are the results.
example with power & factorial lookup table, source.fla
example with Bezier blend value lookup table, source.fla

The speed of the version with lookup tables for Math.pow() and factorial() is now around 42ms in the standalone player, which is about 5 times faster without a big cost. Sure we have a table, but not a big one. The speed of the version with the lookup table for Bezier values is even faster, at around 26ms it’s a good 8 times faster as without lookup tables. Pretty cool huh?

Here’s are two versions using the simple lookup table AS2 class, I mentioned earlier.
class version with simple power & factorial lookup table, source.zip
class version with simple Bezier blend value lookup table, source. zip

I have to admit I’m a bit disappointed at the speed here. The speed for the version with power & factorial lookup tables is around 100ms and the version with the Bezier lookup is 40ms, which is still pretty good. The calculations in the Bezier formula besides factorial and power apparently are pretty difficult as well, but that doesn’t explain why the speed of the power and factorial version went from 42ms in example2 (without AS2 class) to 100ms in example3 (with AS2 class) and why the Bezier version went from 26ms to 40ms. Is fetching from another (class) instance that much of a workload?

And just for the fun of it, here are another two versions using the dynamic lookup table AS2 class.
class version with dynamic power & factorial lookup table, source.zip
class version with dynamic Bezier blend value lookup table, source. zip

The speeds again have diminished. At 365ms, the power & factorial version is the slowest so far, 1.6 times slower than the very first example (which was without lookup tables!). The Bezier version however doesn’t do too bad at a 110ms, which is exactly twice as fast as without lookup tables.

Here’s a table with all the measurements in the standalone player.
table.png

You can see that the more structured and ‘dynamic’ your code is, the heavier the workload in flash becomes, even so much that the dynamic lookup table’s output is only worth it when you use *very* heavy calculations.

- monkey


Ps. Maybe someone cares to adapt my code to make use of curveTo() instead of lineTo()? Could safe a lot of time.

  22 REPLIES
  • of
  • 2
next last page
Codemonkey Author 
1  
Codemonkey

Here’s an experiment I call the JelloWave.

JelloWave.html

You can get the source here

  • 23 August 2005 01:36 PM
  •  
Codemonkey Author 
2  
Codemonkey

And here is a complete demonstration of all the factors.

Globb_a.html

You can get the source here

  • 23 August 2005 01:38 PM
  •  
Ben
3  
Ben

Neat. good

Thanks monkey big grin
Im gonna play around with these.

  • 23 August 2005 01:55 PM
  •  
Mike
4  
Mike

Very cool scripting wormfist yes

Somebody has been busy! I need to put my math hat on for a this stuff. I’ll take a better look tonight. Also at your LookupTable post.

Oh and great examples too!

good

  • 23 August 2005 01:58 PM
  •  
Codemonkey Author 
5  
Codemonkey

Here’s a slightly different version of globb, with a fillcolor. Now it is more like a big pink drop. did I make that pink?? Also, the shape doesn’t break now at the begin- and endpoint

Globb_b.html

And here’s the source

have fun!

  • 23 August 2005 02:09 PM
  •  
Codemonkey Author 
6  
Codemonkey

I just noticed I still have the function calculateEndPoint() on the mathlayer of Globb, which isn’t used anymore. Updated the sources…

  • 23 August 2005 04:31 PM
  •  
Anik
7  
Anik

nice work Codemonkey !!

  • 23 August 2005 04:36 PM
  •  
Codemonkey Author 
8  
Codemonkey

Hey thanks.

Some more experiments here, both are with two different Bezier lines this time.

A donut, fla. And the Globbor, fla. Tried to do something similar to neave.com’s effect on Globbor. My result is rather crude smilie

  • 23 August 2005 10:55 PM
  •  
Renjamin
9  
Renjamin

Awesome work, and thank you!

I’m playing around with this!

smilie good

  • 23 August 2005 11:07 PM
  •  
Codemonkey Author 
10  
Codemonkey

Ok so I’m not finished with Bezier curves yet. Here’s an experiment with mouse trails using Bezier curves. Doubt it’ll be very useful, but what the hey.

Uhm, the controlpoints spawn every Nth onMouseMove cycle, and is dropped into a fifo stack with a window of 10 controlpoints maximum. This is the trail buffer. The controlpoints move towards the next controlpoint ahead of them in queue and so it looks like the entire trail moves along the curve, instead of straight to the mouse.

trailer.html

And here’s the source


Here’s basically the same thing, except I added very badly drawn wheels that rotate along the path so you have a following ‘train’ effect. The wheels are created every odd step in the Bezier curve which now has as many steps as there are controlpoints (the Bezier curve doesn’t need to be smooth anymore), and is only used to determine where the wheels are placed on the curve.

wheeler.html

And here’s the source

  • 21 September 2005 10:19 AM
  •  
Codemonkey Author 
11  
Codemonkey

Here’s a very interesting effect I created while working in the early versions of the previous examples. This example lets you draw a sketch, as if you’ve drawn it with a ‘real’ pen. Ofcourse there are some patterns in it, but barely recognizable (at first glance anyway).

Check what I made:
sketcher.png big grin

Try it your self.
sketcher.html And source

  • 21 September 2005 10:27 AM
  •  
my-tom
12  
my-tom

interesting good

  • 21 September 2005 01:53 PM
  •  
Codemonkey Author 
13  
Codemonkey

Hello everyone,

Here’s a rather big experiment to close this bezier topic off. I wanted to get a bit more familiar with 3D flash so I came up with this, Bezier3D.

Bezier3D.html and source

(You need to let it run a few seconds until the first controlpoints move behind the camera, before it looks like it’s supposed to look).

This example is a little bit bigger, so I took a little bit more care of the directory structure, lots of comments and even two design patterns (Observer and Singleton). Okay, the design patterns weren’t an absolute necessity, but they fit in nicely in my opinion, and they give a good example of how you could use them. There is room for improvement (lots probably), so comments are welcome. I even created a my own simple Tweening engine some time ago which I put to use here. I used it only to animate the camera in 3D space. Read the .as class files for detailed information.

  • 23 September 2005 01:06 PM
  •  
Codemonkey Author 
14  
Codemonkey

For those who requested it, I’ve updated the links that went stale after my old provider removed my ftp space by accident. Have fun.

  • 06 January 2006 07:07 PM
  •  
QaBOjk
15  
QaBOjk

I’ll check back tomorrow, they’re still down

  • 06 January 2006 09:10 PM
  •  
  •   Log in or join for free to make a comment.

Page 1 of 2

  • of
  • 2
next last page
Topic actions
  •  Share on Facebook
  •  Share on Twitter
Topic Categories
  •  Show All Topics
  •  Development
    •  Server Side
    •  Client Side
  •  Creative Software
    •  Web
    •  Video
    •  3D
    •  Illustrator
    •  Photoshop Battles
    •  Photoshop
  •  Design
    •  Typography
    •  Resources & Insight
    •  Checkpoint
  •  Career
    •  Copyright Matters
    •  Advice & issues
    •  Job Seekers
    •  Job Offers
  •  Flash
    •  UltraMath
    •  OOP
    •  Third Party Tools
    •  Open Source alternatives
    •  Data Communication
    •  Components
    •  Flex
    •  AIR
    •  Flash Lite
    •  Flash Professional
    •  Flash Newbie
    •  ActionScript
    •  XML
  •  Lounge
    •  Polls
    •  Random Chat
    •  Showcase And Critique
    •  BombShock Award Nominations
  •  Community Essentials
    •  BombShock Award Winners
    •  Tutorials
    •  Interviews
    •  News
    •  Bitmap tutorials
Popular Topics
  • Sort by: 
  • Activity
  • Views
  • Comments
  • Likes
Advertise with us
  • Your advertisement here!
  • loading
Ultrashock
  • Creative Assets
  • Community
  • Blog
  1. Home
  2. Forum
+/-
Creative Assets
  • Categories
  • Contributors
  • How to buy
Make Money
  • Commission Rates
  • Referral Program
  • Contributor Program
Community
  • Activity Feed
  • Forum
  • Profiles
About
  • Quick Tour
  • Our History
  • Banners & Logos
Support
  • Contact Ultrashock
  • Advertise with us
  • Legal Information
  •  Keep up to date
  • Flash 775  Flash
  • Audio 6,481  Audio
  • Vector 2,130  Vectors
  • Image 12,338  Images
  • Creative Assets 21,724  Assets
  • Profiles 282,659  Members
  • Topics 93,762  Topics
  • Blog 4  Blog
  • Facebook 1,680  Facebook
  • Twitter 1,165  Twitter
  • Join our FREE monthly newsletter!
  • Archive
  • Invalid email address. Please try again.
Subscribe
  • ©2012 Ultrashock LLC - All rights reserved
  • Terms of Use
  • Privacy Policy
  • Switch to dark theme
  • RSS Feeds
  • Top

©2012 Ultrashock LLC - All rights reserved

Printed on Sat, February 04, 2012 - 18:58:50