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

forked from: SuperEllipse

@author Andre Michelle
// forked from AndreMichelle's SuperEllipse
package  
{
	import com.bit101.components.HUISlider;
	
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.geom.Matrix3D;
	import flash.geom.PerspectiveProjection;
	import flash.geom.Utils3D;
	import flash.geom.Vector3D;
	
	/**
	 * @author Andre Michelle
	 */
	[SWF(width='465',height='490',frameRate='50',backgroundColor='0x0')]
	public class SuperEllipse extends Sprite 
	{
		private const proj: PerspectiveProjection = new PerspectiveProjection();
		
		private const ellipse: SuperEllipseGeometry = new SuperEllipseGeometry( 24 ); // PLAY HERE (RESOLUTION)
		
		private const matrix: Matrix3D = new Matrix3D();
		
		private const shape: Shape = new Shape();
		
		private var power1:HUISlider;
		private var power2:HUISlider;
		
		public function SuperEllipse()
		{
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.addEventListener( Event.RESIZE, resize );
			stage.addEventListener( Event.ENTER_FRAME, enterFrame );
			
			addChild( shape );
			
			power1 = new HUISlider(this, 5, 5, 'POWER1');
			power2 = new HUISlider(this, 5, 25, 'POWER2');
			power1.width = power2.width = 300;
			//power1.tick = power2.tick = 0.01;
			power1.minimum = power2.minimum = -0.5;
			power1.maximum = power2.maximum = 5;
			power1.value = power2.value = 1.0;
			power1.labelPrecision = power2.labelPrecision = 3;
			
			resize( null );
		}
		
		private function resize( event: Event ): void
		{
			shape.x = int( stage.stageWidth * .5 );
			shape.y = int( stage.stageHeight * .5 );
		}
		
		private function enterFrame( event: Event ): void
		{
			// DEFINITELY PLAY HERE!!! (SUPER ELLIPSE PARAMETERS)
			// CAUTION VALUES BELOW ZERO ARE POSSIBLE, BUT BLOW UP THE GEOMETRY (NO CLIPPING)
			ellipse.modify( power1.value, power2.value );
			
			matrix.identity();
			matrix.appendScale( 64.0, 64.0, 64.0 );
			matrix.appendRotation( shape.mouseX * .5, Vector3D.Y_AXIS );
			matrix.appendRotation(-shape.mouseY * .5, Vector3D.X_AXIS );
			matrix.appendTranslation( 0.0, 0.0, 128.0 );
			matrix.transformVectors( ellipse.wVerts, ellipse.tVerts );
			proj.fieldOfView = 75.0;
			Utils3D.projectVectors( proj.toMatrix3D(), ellipse.tVerts, ellipse.projectedVerts, ellipse.uvts );
			
			ellipse.drawQuadStrip( shape.graphics );
		}
	}
}

import flash.display.Graphics;

/**
 * http://ozviz.wasp.uwa.edu.au/~pbourke/geometry/superellipse/
 */
class SuperEllipseGeometry
{
	private const TWOPI: Number = Math.PI * 2.0;
	private const PID2: Number = Math.PI * 0.5;
	
	private var _n: int;
	private var _p: P;
	
	public var wVerts: Vector.<Number>;
	public var tVerts: Vector.<Number>;
	public var uvts: Vector.<Number>;
	public var projectedVerts: Vector.<Number>;
	public var quadsNum: int;
	public var vertsNum: int;
	public var quads: Vector.<int>;
	
	public function SuperEllipseGeometry( n: int )
	{
		_n = n;
		
		_init();
	}
	
	public function modify( power1: Number, power2: Number ): void
	{
		var tmp: Number;
		var i: int = -1;
		var p: P = _p;
		
		var x: Number;
		var y: Number;
		var z: Number;
		
		while( p )
		{
			if( 0.0 == p.abs_ct1 )
				tmp = 0.0;
			else
				tmp = p.sgn_ct1 * Math.pow( p.abs_ct1, power1 );
			
			if( 0.0 == p.abs_ct2 )
				x = 0.0;
			else
				x = tmp * p.sgn_ct2 * Math.pow( p.abs_ct2, power2 );
			
			if( 0.0 == p.abs_st1 )
				y = 0.0;
			else
				y = p.sgn_st1 * Math.pow( p.abs_st1, power1 );
			
			if( 0.0 == p.abs_st2 )
				z = 0.0;
			else
				z = tmp * p.sgn_st2 * Math.pow( p.abs_st2, power2 );
			
			wVerts[ ++i ] = x;
			wVerts[ ++i ] = y;
			wVerts[ ++i ] = z;
			
			p = p.next;
		}
	}
	
	public function drawQuadStrip( graphics: Graphics ): void
	{
		graphics.clear();
		graphics.lineStyle( 0, 0xFFFFFF, 0.5 );
		
		var qi: int;
		var pi: int;
		var x0: Number;
		var y0: Number;
		
		var i: int = 0;
		var n: int = quadsNum;
		
		for( ; i < n ; ++i )
		{
			qi = i << 2;
			
			pi = quads[qi] << 1;
			graphics.moveTo( x0 = projectedVerts[ pi ], y0 = projectedVerts[ ++pi ] );
			
			pi = quads[++qi] << 1;
			graphics.lineTo( projectedVerts[ pi ], projectedVerts[ ++pi ] );
			
			pi = quads[++qi] << 1;
			graphics.lineTo( projectedVerts[ pi ], projectedVerts[ ++pi ] );
			
			pi = quads[++qi] << 1;
			graphics.lineTo( projectedVerts[ pi ], projectedVerts[ ++pi ] );
			
			graphics.lineTo( x0, y0 );
		}
	}
	
	/*
	BUILDING GEOMETRY
	*/
	private function _init(): void
	{
		vertsNum = ( ( _n >> 1 ) + 1 ) * _n;
		quadsNum = vertsNum - _n;
		
		wVerts = new Vector.<Number>( vertsNum * 3, true );
		tVerts = new Vector.<Number>( vertsNum * 3, true );
		uvts = new Vector.<Number>( vertsNum * 3, true );
		projectedVerts = new Vector.<Number>( vertsNum * 2, true );
		quads = new Vector.<int>( quadsNum << 2, true );
		
		var i: int;
		var j: int;
		var nh: int = _n >> 1;
		
		var t1: Number;
		var t2: Number;
		
		var iInv: Number = 1.0 / _n;
		var pn: Number = TWOPI / _n;
		
		var uvi: int = -1;
		
		var ct1: Number;
		var ct2: Number;
		var st1: Number;
		var st2: Number;
		
		var qi: int = -1;
		var jn: int;
		
		var p: P;
		
		for( j = 0 ; j <= nh ; ++j )
		{
			t1 = j * pn - PID2;
			
			for( i = 0 ; i < _n ; ++i )
			{
				if( i == 0 )
					t2 = 0.0;
				else
					t2 = i * pn;
				
				if( null == p )
					p = _p = new P();
				else
					p = p.next = new P();
				
				ct1 = Math.cos( t1 );
				ct2 = Math.cos( t2 );
				st1 = Math.sin( t1 );
				st2 = Math.sin( t2 );
				
				if( ct1 < 0.0 )
				{
					p.abs_ct1 = -ct1;
					p.sgn_ct1 = -1.0;
				}
				else
				{
					p.abs_ct1 = ct1;
					p.sgn_ct1 = 1.0;
				}
				
				if( ct2 < 0.0 )
				{
					p.abs_ct2 = -ct2;
					p.sgn_ct2 = -1.0;
				}
				else
				{
					p.abs_ct2 = ct2;
					p.sgn_ct2 = 1.0;
				}
				
				if( st1 < 0.0 )
				{
					p.abs_st1 = -st1;
					p.sgn_st1 = -1.0;
				}
				else
				{
					p.abs_st1 = st1;
					p.sgn_st1 = 1.0;
				}
				
				if( st2 < 0.0 )
				{
					p.abs_st2 = -st2;
					p.sgn_st2 = -1.0;
				}
				else
				{
					p.abs_st2 = st2;
					p.sgn_st2 = 1.0;
				}
				
				//-- NOT USED, BUT GO AHEAD > ADD TEXTURES
				uvts[ ++uvi ] = i * iInv;
				uvts[ ++uvi ] = 2.0 * j * iInv;
				uvts[ ++uvi ] = 0.0;
				
				if( j > 0 )
				{
					jn = j * _n;
					
					if( i > 0 )
					{
						quads[++qi] = ( j - 1 ) * _n + i - 1; 
						quads[++qi] = ( j - 1 ) * _n + i;
						quads[++qi] = jn + i;
						quads[++qi] = jn + i - 1;
					}
					else
					{
						quads[++qi] = jn - 1; 
						quads[++qi] = ( j - 1 ) * _n;
						quads[++qi] = jn;
						quads[++qi] = ( j + 1 ) * _n - 1;
					}
				}
			}
		}
	}
}

class P
{
	public var abs_ct1: Number;
	public var abs_ct2: Number;
	public var abs_st1: Number;
	public var abs_st2: Number;
	
	public var sgn_ct1: Number;
	public var sgn_ct2: Number;
	public var sgn_st1: Number;
	public var sgn_st2: Number;
	
	public var next: P;
}