In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

PV3D Bezier Ribbons

PV3D Bezier Ribbons
* @author Marco Di Giuseppe
* @see http://designmarco.com
* @since 5/6/09
/**
 * Copyright marco ( http://wonderfl.net/user/marco )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/cfep
 */

/**
 * PV3D Bezier Ribbons
 * @author Marco Di Giuseppe
 * @see http://designmarco.com
 * @since 5/6/09
 */
package 
{
	import flash.events.Event;
	import flash.events.MouseEvent;

	import org.papervision3d.view.BasicView;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.DisplayObject3D;

	import net.hires.debug.Stats;

	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="60")]

	public class BezierRibbons extends BasicView
	{
		private static const NUM_RIBBONS:int = 3;
		private var mouseDown:Boolean;
		private var ribbons:Array;
		private var ribbonColors:Array;
		private var xpos:Number;
		private var ypos:Number;
		private var ribbon:Ribbon;
		public var holder:DisplayObject3D;

		public function BezierRibbons()
		{
			super(465, 465);
			init();
		}

		private function init():void
		{
			camera.focus = 11;
			camera.zoom = 100;
			
			holder = new DisplayObject3D();
			scene.addChild(holder);
						
			ribbonColors = [0xFF0000, 0xFFFFFF, 0x33CCFF];
			ribbons = [];
			
			var i:int = NUM_RIBBONS;
			while( --i > -1 )
			{
				ribbon = new Ribbon(this, ribbonColors[i]);
				ribbons[ribbons.length] = ribbon;
			}

			stage.addEventListener(Event.ENTER_FRAME, render, false, 0, true);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseHandler, false, 0, true);
			stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseHandler, false, 0, true);
			addChild(new Stats());
		}

		private function render(event:Event):void
		{
			xpos = ((stage.mouseX - stage.stageWidth * 0.5) / stage.stageWidth) * 180;
			ypos = ((stage.mouseY - stage.stageHeight * 0.5) / stage.stageHeight) * 180;

			if (mouseDown)
			{
				holder.rotationY += (xpos - holder.rotationY) * 0.2;
				holder.rotationX += (ypos - holder.rotationX) * 0.2;
				holder.rotationZ += (ypos - holder.rotationZ) * 0.2;
			}
                        else holder.roll(0.1);
			singleRender();
		}

		private function mouseHandler(event:MouseEvent):void
		{
			mouseDown = !mouseDown;
		}

		public function reset():void
		{
			var i:int = NUM_RIBBONS;
			while( --i > -1 )
			{
				ribbons[i].remove();
			}
			init();
		}
	}
}

import flash.utils.Timer;
import flash.events.TimerEvent;

import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.objects.DisplayObject3D;

class Ribbon extends DisplayObject3D
{
	private static const RIBBON_LENGTH:Number = 300;
	private static const RIBBON_WIDTH:Number = 3;
	private static const CURVE_QUALITY:int = 50;
	private static const NUM_CURVES:int = 5;
	private var ribbon:BezierRibbons;
	private var stepId:int;
	private var curves:Array;
	private var points:Array;
	private var color:uint;
	private var cLen:int;
	private var curve:Curve;

	public function Ribbon(ribbon:BezierRibbons, color:uint)
	{
		this.ribbon = ribbon;
		this.color = color;
		this.ribbon.holder.addChild(this);
		
		curves = [];
		points = [];
			
		points[points.length] = new Vertex3D();
		points[points.length] = new Vertex3D();
		points[points.length] = new Vertex3D();
			
		var timer:Timer = new Timer(10);
		timer.addEventListener(TimerEvent.TIMER, onRender, false, 0, true);
		timer.start();
		
		addCurve();
	}

	public function onRender(event:TimerEvent):void
	{
		cLen = curves.length;
		curves[cLen - 1].addLine();
		if (cLen > NUM_CURVES - 1) curves[0].removeLine();
		if (stepId++ > CURVE_QUALITY)	addCurve();
	}

	private function addCurve():void
	{
		addNextPoint();
			
		var pLen:int = points.length;
		var nextPt:Vertex3D = points[pLen - 1];
		var curPt:Vertex3D = points[pLen - 2];
		var lastPt:Vertex3D = points[pLen - 3];
		var xx:Number = (curPt.x + lastPt.x) * 0.5;
		var yy:Number = (curPt.y + lastPt.y) * 0.5;
		var zz:Number = (curPt.z + lastPt.z) * 0.5;
		var mx:Number = (curPt.x + nextPt.x) * 0.5;
		var my:Number = (curPt.y + nextPt.y) * 0.5;
		var mz:Number = (curPt.z + nextPt.z) * 0.5;
			
		var lastMidPt:Vertex3D = new Vertex3D(xx, yy, zz);
		var midPt:Vertex3D = new Vertex3D(mx, my, mz);
			
		curve = new Curve(lastMidPt, midPt, curPt, color, RIBBON_WIDTH, CURVE_QUALITY);
		curves[curves.length] = curve;
		addChild(curve);
			
		var oldCurve:Curve;
		var cLen:int = curves.length;
		if (cLen > NUM_CURVES)
		{
			oldCurve = curves.shift();
			removeChild(oldCurve);
			oldCurve.remove();
			points.shift();
		}
		stepId = 0;
	}

	private function addNextPoint():void
	{			
		var xdelta:Number = randomInRange(0, RIBBON_LENGTH);
		if (Math.random() < 0.5) xdelta = -xdelta;
			
		var ydelta:Number = randomInRange(0, RIBBON_LENGTH);
		if (Math.random() < 0.5) ydelta = -ydelta;
			
		var zdelta:Number = randomInRange(0, RIBBON_LENGTH);
		if (Math.random() < 0.5) zdelta = -zdelta;

		var nextPt:Vertex3D = new Vertex3D(xdelta, ydelta, zdelta);
		points[points.length] = nextPt;
	}

	public function float(min:Number, max:Number = NaN):Number
	{
		if (isNaN(max)) 
		{ 
			max = min; 
			min = 0; 
		}
		return Math.random() * (max - min) + min;
	}

	public function randomInRange(min:Number, max:Number):int
	{
		return int((max - min) * float(2) + min);
	}

	public function remove():void
	{
		var i:int = curves.length;
		while( --i > -1 )
		{
			curves[i].remove();
		}
		delete(this);
	}
}

import org.papervision3d.core.geom.TriangleMesh3D;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.NumberUV;
import org.papervision3d.materials.ColorMaterial;

class Curve extends TriangleMesh3D
{
	private var stepId:int;
	private var width:Number;
	private var quality:int;
	private var startPt:Vertex3D;
	private var endPt:Vertex3D;
	private var controlPt:Vertex3D;

	public function Curve( startPt:Vertex3D, endPt:Vertex3D, controlPt:Vertex3D, color:uint, width:Number, quality:int)
	{
		this.startPt = startPt;
		this.endPt = endPt;
		this.controlPt = controlPt;
		this.width = width;
		this.quality = quality;
			
		var cm:ColorMaterial = new ColorMaterial(color);
		cm.doubleSided = cm.tiled = cm.smooth = true;
			
		super(cm, [], [], null);
	}

	public function addLine():void
	{
		var t:Number = stepId / quality;
		var p0:Vertex3D = getOffsetPoint(t, 0);
		var p3:Vertex3D = getOffsetPoint(t, width);
			
		stepId++;
			
		t = stepId / quality;
		var p1:Vertex3D = getOffsetPoint(t, 0);
		var p2:Vertex3D = getOffsetPoint(t, width);
			
		addLineToMesh(p0, p1, p2, p3);
	}

	public function addLineToMesh(aV:Vertex3D, bV:Vertex3D, cV:Vertex3D, dV:Vertex3D):void
	{
		var vertices:Array = this.geometry.vertices;
		var faces:Array = this.geometry.faces;
							
		vertices[vertices.length] = aV;
		vertices[vertices.length] = bV;
		vertices[vertices.length] = cV;
		vertices[vertices.length] = dV;

		var uvA:NumberUV = new NumberUV(0, 0);
		faces[faces.length] = new Triangle3D(this, [aV, bV, cV], null, [uvA, uvA, uvA]);
		faces[faces.length] = new Triangle3D(this, [aV, cV, dV], null, [uvA, uvA, uvA]);
	}

	public function removeLine():void
	{
		this.geometry.vertices.shift();
		this.geometry.vertices.shift();
		this.geometry.vertices.shift();
		this.geometry.vertices.shift();
		this.geometry.faces.shift();
		this.geometry.faces.shift();
	}

	private function getOffsetPoint( t:Number, k:Number ):Vertex3D
	{
		var p0:Vertex3D = startPt;
		var p1:Vertex3D = controlPt;
		var p2:Vertex3D = endPt;
			
		var xt:Number = ( 1 - t ) * ( 1 - t ) * p0.x + 2 * t * ( 1 - t ) * p1.x + t * t * p2.x;
		var yt:Number = ( 1 - t ) * ( 1 - t ) * p0.y + 2 * t * ( 1 - t ) * p1.y + t * t * p2.y;
		var zt:Number = ( 1 - t ) * ( 1 - t ) * p0.z + 2 * t * ( 1 - t ) * p1.z + t * t * p2.z;
			
		var xd:Number = t * (p0.x - 2 * p1.x + p2.x) - p0.x + p1.x;
		var yd:Number = t * (p0.y - 2 * p1.y + p2.y) - p0.y + p1.y;
		var zd:Number = t * (p0.z - 2 * p1.z + p2.z) - p0.z + p1.z;
		var dd:Number = Math.pow(xd * xd + yd * yd + zd * zd, .33);
			
		return new Vertex3D(xt + ( k * yd ) / dd, yt - ( k * xd ) / dd, zt - ( k * xd ) / dd);
	}

	public function remove():void
	{
		delete(this);
	}
}