Aug 07, 2009

Supershapes - Coder Challenge

Charlie discovered the idea of the super formula. Since it sounded super, Charlie proposed a challenge, a coder challenge, a super coder challenge. The challenge was straightforward – create a super formula editor that creates a super shape. The other parameters being that the shape must spin in 3D (well at least look like it), the shape must be composed of at least 10,000 particles, the shape must be editable and it must be made in Flash. The winner determined by the fastest FPS, as judged by Mr Doobs stats class.

The super formula is as follows, thanks wikipedia:

932649147ef032f63b06bafbd22d2554

Many different shapes can be derived from this formula by changing m, n1, n2 and n3. Some of the combinations are :

superformula

Many optimization techniques were used to get those particles to form the unique shapes and spin at the same time. Everyone saw a large increase in FPS when using the bitmapdata.lock() method. All of the images captured were on a Dual 2 GHz PowerPC G5 with 3.5 GB Ram while testing the .swf files locally.

Ben's Solution:

ben_bojko_supershapes

Ben used an approximation for sine that allowed him to compute his rotation values, eliminating the more expensive sine and cos function call.

public static var SIN1:Number	= 1.27323954;
public static var SIN2:Number	= 0.405284735;
// ---------- FastMath Sin/Cos ----------
if ( _rotY < -PI )	_rotY += P2;
//compute sine
if (_rotY  > PI)	 _rotY -= P2;
//compute cosine
if (_rotY < 0)	_rotYCos = SIN1 * _rotY + SIN2 * _rotY * _rotY;
else			_rotYCos = SIN1 * _rotY - SIN2 * _rotY * _rotY;
_rotY -= 1.57079632;
// --------------------------------------



Charlie's Solution:

charlie_whitney_supershapes

Charlie took a more object oriented approach and created a separate particle class to store the next particle to alter in his while loop. He got this linked list approach from Joa Ebert's blog.

var p	:Particle = _firstParticle;
...
var adjustX	:Number = Math.cos(_inc);
var adjustY	:Number = Math.sin(_inc);
_inc += 0.05;
 
_bmd.lock();
_bmd.fillRect(_bmd.rect, 0xFFFFFF);
 
while(p.next != null){
	_phi = p.num * PI_OVER_NUM;
       t1 = Math.cos(m * _phi / 4) / a;
	if(t1<0) t1 = -t1;	//abs
	t1 = Math.pow(t1,n2);
       ...
       p = p.next;
}


Nick's Solution:

nick_hardeman_supershapes

The computations were killing the cpu, even simple multiplication or division, so I decided to create a look-up table using my favorite class the Vector,  to take care of the heavier operations. These tables are calculated when one of the parameters are changed and hold every calculation for many thousands of particles. I am sure they could be optimized by using approximation, to hold many less numbers. I tried every loop that I could think of, but I found that this enterframe for loop gave me the most speed.

 
// enterframe loop //
for (i = 0; i >= 0; i--) { ... }
 
// setup //
var i:int = 0;
for (i = 0; i < numPoints; i++) {
	_theta += angleInc;
	lookupAnglesX[i] = Math.cos(_theta);
	lookupAnglesY[i] = Math.sin(_theta);
	lookupAnglesT[i] = (m * _theta) * .25;
	lookupAnglesT_sin[i] = Math.sin(lookupAnglesT[i]);
	lookupAnglesT_cos[i] = Math.cos(lookupAnglesT[i]);
}


So to sum it up, sine and cos approximations, oop approaches and look-up tables will give you a boost in FPS, at least in the case of super shapes. So Big Spaceship extends the challenge to the flashy community and we look forward to any new questions, comments, solutions, optimizations, tips, tricks, feedback and anything else even somewhat relevant.

So dig through and rip apart the source. All three examples are included.
Super Shapes Source









Share this Post


                           

Comments


Chiara Panda Lernspiele     Sep 02, 2009
OMG, Charlie, that's really a good job! No OpenFrameworks or Processing? That sounds amazing...

Si Robertson     Aug 27, 2009
You could reduce the work the CPU has to do by pushing each particle through a transformation matrix - you would only need to use cos and sin once to set the orientation of the matrix before pushing the particle coordinates through it.

Just a thought. :)

Harley Parks     Aug 26, 2009
hey.. very cool idea... any updates?



Jas Festywal     Aug 21, 2009
Charlie - great work. Genius old boy.

mrsanders     Aug 13, 2009
Please tell how its the name of the blue squared panel, with FPS, MS, etc., and how can i used!
Thanks!

NickHardeman     Aug 11, 2009
No Alchemy / Pixel Blender for the contest and no OpenFrameworks, or Processing either, haha.

Ringo     Aug 09, 2009
Sweet, hope i have some time for this:)

Here me first quick try to optimize it:
http://www.flashbookmarks.com/demos/supershapecompo/

based on the lookups (10k part.)

Getting around 220-270 fps

Pierluigi Pesenti     Aug 08, 2009
I am in. And quote Peter about the question.

Sebastian     Aug 08, 2009
You have to fix something in the code display:

for (i = 0; i >= 0; i--) { ... }


Peter Nitsch     Aug 07, 2009
Love this idea. Any restrictions with regards to Alchemy/Pixel Bender?


Speak






Submit »