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

sphere

透明な球体の頂点に、あたかも丸いシールが貼り付いているかのように見える 3D 表現
 * 2009/01/19 Stats 追加
Get Adobe Flash player
by Aquioux 29 Jun 2009
/* 透明な球体の頂点に、あたかも丸いシールが貼り付いているかのように見える 3D 表現
 * 2009/01/19 Stats 追加
 */
package {
	/**
	 * @author YOSHIDA, Akio
	 * http://aquioux.blog48.fc2.com/blog-entry-538.html
	 */
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Vector3D;
	import flash.geom.Matrix3D;
	import flash.geom.PerspectiveProjection;
	import net.hires.debug.Stats;

	[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "#000000")]

	public class Main extends Sprite {
                Wonderfl.capture_delay(10);

		// 3D オブジェクトのコンテナ
		private var rootNode:Sprite;
		// 頂点
		private var vctrVertics:Vector.<Vertex>;
		// プロジェクション
		private var fov:PerspectiveProjection;
		
		// 回転に関わる変数
		private var aX:Number = 0;
		private var aY:Number = 0;
		
		// 中心から頂点までの距離
		private const DIST:uint = 200;


		public function Main() {
    
			createProjection();	// プロジェクション生成
			createContainer();	// 3D コンテナ生成
			createVertics();	// 頂点生成
			
			this.addChild(new Stats());
			
                        // イベントハンドラ
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
		}


		// イベントハンドラ
		private function onEnterFrameHandler(e:Event):void {
			aX += rootNode.mouseX*0.005;
			aY -= rootNode.mouseY*0.005;

			// 変換行列生成
			var mat:Matrix3D = new Matrix3D();
			// 回転を変換行列に合成
			mat.appendRotation(aX, Vector3D.Y_AXIS);
			mat.appendRotation(aY, Vector3D.X_AXIS);

			perspective(mat, fov);	// 投影
			zsort();				// Zソート
		}
		// 投影
		private function perspective(mat:Matrix3D, fov:PerspectiveProjection):void {
			for each (var element:Vertex in vctrVertics) {
				element.render(mat, fov, DIST);
			}
		}
		// Zソート
		private function zsort():void {
			vctrVertics.sort( function(x:Vertex, y:Vertex):Number { return y.z - x.z; } );
			var len:uint = vctrVertics.length;
			var i:int = len;
			while(i--) { rootNode.setChildIndex(vctrVertics[i], len-1); }
		}


		// プロジェクション生成
		private function createProjection():void {
			fov = new PerspectiveProjection();
			fov.fieldOfView = 60;		// 視野角の設定
		}
		// 3D コンテナ生成
		private function createContainer():void{
			rootNode = new Sprite();
			rootNode.x = stage.stageWidth / 2;
			rootNode.y = stage.stageHeight / 2;
			rootNode.z = 250;
			addChild(rootNode);
		}
		// 頂点生成
		private function createVertics():void {
			var baseNum:uint = 4;
			var vNum:uint = baseNum * 2;
			var hNum:uint = baseNum * 2;
			
			// theta:シータ(θ)は緯度、phi:ファイ(φ)は経度
			var theta:Number = Math.PI / (vNum + 1);
			var phi:Number   = Math.PI * 2 / hNum;
			
			vctrVertics = new Vector.<Vertex>();
			var i:uint = 0;
			for (var v:int = 0; v < vNum ; v++) {
				for (var h:int = 0; h < hNum ; h++) {
					var px:Number = DIST * Math.sin(theta*(v+1)) * Math.cos(phi*h);
					var pz:Number = DIST * Math.sin(theta*(v+1)) * Math.sin(phi*h);
					var py:Number = DIST * Math.cos(theta*(v+1));
					var vertex:Vertex = new Vertex(px, py, pz);
					rootNode.addChild(vertex);
					vctrVertics.push(vertex);
				}
			}
		}
	}
}


/*
 * 頂点クラス
 */
import flash.display.Shape;
import flash.geom.Vector3D;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.ColorTransform;

class Vertex extends Shape {
	private var home:Vector3D = new Vector3D();	// 座標ホームポジション
	private var proj:Vector3D = new Vector3D();	// 投影座標
	
	public function Vertex(x:Number, y:Number, z:Number) {
		this.x = home.x = x;
		this.y = home.y = y;
		this.z = home.z = z;
		// 描画
		graphics.beginFill(0xffffff);
		graphics.drawCircle(0, 0, 20);
		graphics.endFill();
	}
	
	public function render(mat:Matrix3D, fov:PerspectiveProjection, dist:uint):void {
		// 投影座標を計算し、自分自身(表示オブジェクト)に適用する
		proj = mat.transformVector(home);
		proj.w = fov.focalLength / (fov.focalLength + proj.z);
		proj.project();
		x = proj.x;
		y = proj.y;
		z = proj.z;
		scaleX = scaleY = 1 / proj.w;
		
		// 円が球体に貼り付いているように見せるために円を歪ませる処理
		rotation = Math.atan2(y, x) / Math.PI * 180;
		scaleX = z / dist;
		
		// 円に裏と表があるように見せるために色を変える処理
		var ct:ColorTransform = new ColorTransform();
		(z > 0) ? ct.color = 0xffcc00 : ct.color = 0xcc0000;
		transform.colorTransform = ct;
	}
}