HeartWorm
Forked: one of LOVE MATRIX worm: a study for drawing curl curve.
But I do not remember which one.
/**
* Forked: one of LOVE MATRIX worm: a study for drawing curl curve.
* But I do not remember which one.
*
* Comments form origin:
* forked from nutsu's Worm like a fractal.
* forked from nutsu's Draw worm by mouse gesture.
* forked from nutsu's Worm matrix based.
* LOVE MATRIX
* a study for drawing curl curve.
* license under the GNU Lesser General Public License.
*/
package
{
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.filters.BlurFilter;
import flash.filters.GlowFilter;
import flash.geom.Point;
import frocessing.display.F5MovieClip2DBmp;
import frocessing.geom.FMatrix2D;
import flash.geom.ColorTransform;
public class HeartWorm extends F5MovieClip2DBmp
{
private var vms:Array;
private var MAX_NUM:int = 500;
private var N:Number = 580;
private var worm_flg:Boolean = false;
private var countValues:int = 0;
private var prev_x:Number = 0;
private var prev_y:Number = 0;
private var countHeartElem:int = 0;
private var col:uint = 0x000000;//0xFFFFFF;
private var bgcol:uint = 0xFFFFFF;//0x000000;
private var needFeel:Boolean = false;
public function HeartWorm()
{
super(false, 0xffffffff);
stage.frameRate = 60;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
vms = [];
}
public function initCurlObject(x:Number, y:Number, angle:Number):void
{
var len:Number = 10;
var mtx:FMatrix2D = new FMatrix2D();
mtx.tx = x;
mtx.ty = y;
mtx.prependRotation(angle);
createObj(mtx, len, angle);
}
public function createObj(mtx:FMatrix2D, len:Number, ang:Number = 0):void
{
if (vms.length > MAX_NUM)
return;
var angle:Number
if (ang != 0)
{
angle = random(PI / 64, PI / 12);
angle *= Math.random() < 0.5 ? 1 : -1;
}
else
{
angle = random(PI / 64, PI / 12);
}
var tmt:FMatrix2D = new FMatrix2D();
tmt.scale(0.95, 0.95);
tmt.rotate(angle);
tmt.translate(len, 0);
var w:Number = len / 5;
var obj:WormObject = new WormObject();
obj.c1x = obj.p1x = -w * mtx.c + mtx.tx;
obj.c1y = obj.p1y = -w * mtx.d + mtx.ty;
obj.c2x = obj.p2x = w * mtx.c + mtx.tx;
obj.c2y = obj.p2y = w * mtx.d + mtx.ty;
obj.vmt = mtx;
obj.tmt = tmt;
obj.r = angle;
obj.w = w;
obj.len = len;
obj.count = 0;
vms.push(obj);
}
private function drawHeartElem(countHeartElem:int):void
{
var p:Point = getNextValue(countHeartElem);
if (prev_x != 0 && prev_y != 0)
{
moveTo(prev_x, prev_y);
curveTo(prev_x, prev_y, p.x, p.y);
lineTo(p.x, p.y);
curveTo(p.x, p.y, prev_x, prev_y);
var angle:Number = Math.atan2(p.y - prev_y, p.x - prev_x);
initCurlObject(prev_x, prev_y, angle);
}
prev_x = p.x;
prev_y = p.y;
closePath();
}
private function getNextValue(countValues:int):Point
{
var t:Number = countValues * Math.PI / 180;
t *= 2.5;
var x:Number = 16 * Math.sin(t) * Math.sin(t) * Math.sin(t);
var y:Number = 13 * Math.cos(t) - 5 * Math.cos(2 * t) - 2 * Math.cos(3 * t) - Math.cos(4 * t);
x *= 10;
y *= -10;
y -= 20;
return new Point(x, y);
}
public function setup():void
{
size(stage.stageWidth, stage.stageHeight);
background(bgcol);
}
public function draw():void
{
translate(fg.width / 2, fg.height / 2);
if (isMousePressed)
{
background(bgcol);
vms = [];
countHeartElem = 0;
}
if (countHeartElem < 150)
{
drawHeartElem(countHeartElem);
countHeartElem++;
}
;
var len:int = vms.length;
for (var i:int = 0; i < len; i++)
{
var o:WormObject = vms[i];
if (o.count < N)
{
o.count++;
drawCurl(o);
}
else
{ len--;
vms.splice(i, 1);
i--;
}
}
smooth();
}
public function mouseReleased():void
{
vms = [];
worm_flg = !worm_flg;
countHeartElem = 0;
}
public function drawCurl(obj:WormObject):void
{
if (Math.random() < 0.015)
{
var mtx:FMatrix2D = FMatrix2D(obj.vmt.clone());
mtx.prependScale(1, -1);
createObj(mtx, obj.len);
}
if (worm_flg && Math.random() < 0.1)
{
obj.tmt.rotate(-obj.r * 2);
obj.r *= -1;
}
obj.vmt.prepend(obj.tmt);
var cc1x:Number = -obj.w * obj.vmt.c + obj.vmt.tx;
var cc1y:Number = -obj.w * obj.vmt.d + obj.vmt.ty;
var pp1x:Number = (obj.c1x + cc1x) / 2;
var pp1y:Number = (obj.c1y + cc1y) / 2;
var cc2x:Number = obj.w * obj.vmt.c + obj.vmt.tx;
var cc2y:Number = obj.w * obj.vmt.d + obj.vmt.ty;
var pp2x:Number = (obj.c2x + cc2x) / 2;
var pp2y:Number = (obj.c2y + cc2y) / 2;
if (needFeel) {
beginFill(col);
}
lineStyle(1, col);
moveTo(obj.p1x, obj.p1y);
curveTo(obj.c1x, obj.c1y, pp1x, pp1y);
lineTo(pp2x, pp2y);
curveTo(obj.c2x, obj.c2y, obj.p2x, obj.p2y);
closePath();
if (needFeel) {
endFill();
}
obj.c1x = cc1x;
obj.c1y = cc1y;
obj.p1x = pp1x;
obj.p1y = pp1y;
obj.c2x = cc2x;
obj.c2y = cc2y;
obj.p2x = pp2x;
obj.p2y = pp2y;
}
}
}
import frocessing.geom.FMatrix2D;
class WormObject
{
public var c1x:Number;
public var c1y:Number;
public var c2x:Number;
public var c2y:Number;
public var p1x:Number;
public var p1y:Number;
public var p2x:Number;
public var p2y:Number;
public var w:Number;
public var r:Number;
public var len:Number;
public var count:int;
public var vmt:FMatrix2D;
public var tmt:FMatrix2D;
public function WormObject()
{
}
}