19 February 2010

Coding spiderwebs in ActionScript3.0

After last post on AS2 wedge class I've done some research about geometry (thanks to comments by Steven), how to find coordinates of different points on circle if you know radius, center and angles and some interesting results show up which I'll present here. However I think I should move on further away from drawing API since last several posts were on same subject.

Another thing I wanted to write about is my Flash2nd project and newly formed Facebook Fan Page. I have released 58 clocks until day, latest one Obama clock (I don't have any political views what so ever). Check it out and download some free clocks.






Coding spiderwebs

First of all, I'll give you entire code for spiderweb class and than we'll discuss it.

spiderweb.as

package
{
import flash.display.Sprite;
import flash.geom.Point;

public class spiderweb extends Sprite
{
private var _circles:uint;
private var _nods:uint;
private var _df:Number; // circles distance factor
private var _fr:Number; // first circle radius

public function spiderweb(circles:uint, nods:uint, fr:Number, df:Number)
{
_circles = circles;
_nods = nods;
_fr = fr;
_df = df;

init();
}

private function init():void
{

var cx = 0;
var cy = 0;
var angles:Array = new Array();
var coords:Array = new Array();
var angle:Number;
var currR:Number;
var angleStep:Number = 360 / _nods;
currR = _fr;

for(var k:uint = 0; k < _circles; k++)
{
currR += currR * _df;

for (var i:uint = 0; i < _nods; i++)
{
angle = angleStep * (i + 1);
angle = angle * Math.PI / 180;
angles[i] = angle;
var x1:Number = trim(currR * Math.cos(angle));
var y1:Number = trim(currR * Math.sin(angle));

var point:Point = new Point(x1, y1);
coords.push(point);

}

drawStraights(coords);
drawCurves(coords);
// trace(coords);
coords.splice(0, _nods);
}
}

private function trim(num:Number):Number
{
var nstr:int = int(num*100);
return Number(nstr / 100);
}

private function drawStraights(array:Array):void
{
this.graphics.lineStyle(1, 0xffffff);
this.graphics.moveTo(0,0);
for (var i:uint = 0; i < array.length; i++)
{
this.graphics.lineTo(array[i].x, array[i].y);
this.graphics.moveTo(0,0);
}
}

private function drawCurves(array2:Array):void
{

var extA:Array = new Array();
extA = array2;
this.graphics.lineStyle(2, 0xffffff);
for (var j:uint = 0; j < extA.length-1; j++)
{
this.graphics.moveTo(0,0);
this.graphics.moveTo(extA[j].x, extA[j].y);
this.graphics.curveTo(0, 0, extA[j+1].x, extA[j+1].y);
this.graphics.moveTo(0,0);
}
this.graphics.moveTo(extA[extA.length-1].x, extA[extA.length-1].y);
this.graphics.curveTo(0, 0, extA[0].x, extA[0].y);
}
}
}


This class extends Sprite class, so we can take advantages of drawing API (once again). Don't worry about private variables, we will explain that later when I present test class.

What this class does is draws spiderweb dinamically using few predefined properties. When you think about it, perfect spiderweb has same angles between any thread, so we only need to define single angle as parameter and fill new angles Array with other values which depends on number of threads we want to draw (which is another parameter). Init function first creates two Arrays, just mentioned angles and coords Array which will hold coordinate points of each threads intersection! This will change on every thread iteration using for loop.

We have separate functions drawStraights and drawCurves and simple trim function because we need points coordinates cut to two decimal points. Take a look at drawCurves function when after for loop we have additional step. Now, this code can be improved by changing control points for drawing curves. In this case we used (0,0) point, but real life web would have control points somewhere closer to circle thread, not center of the web. This can be easily calculated and stored within new Array.

Now, let's see how test class looks like:

sptest.as

package
{
import spiderweb;
import flash.display.Sprite;

public class sptest extends Sprite
{
public function sptest()
{
var sp:spiderweb = new spiderweb(6, 16, 40, 0.4);
addChild(sp);
sp.x = stage.stageWidth / 2;
sp.y = stage.stageHeight / 2;
}
}
}


That's all ! Long live OOP. Let's take a look at parameters you can change.

new spiderweb(a, b, c, d);

a - number of circular threads to draw
b - number of points on any given circular thread
c - radius of first circular thread
d - distance factor

Here is how distance factor works. If you set parameter c = 100 you will have 100 for first circular thread radius and than 100 + (100 * d) for second, etc, which means threads will be closer and closer to each other. In this way we can mimic real life spiderweb look.

Finally, here are some examples.



*_*

0 comments:

 

template by blogger templates