Beautifl - Flash Gallery

Thumbnail : simple 3D 01 (not using PV3D)
simple 3D 01 (not using PV3D)
sakef 2010-06-03 MIT License

再生するにはFlash Playerが必要です。デスクトップのブラウザでご覧ください。

/*
	もうすぐ3D本出るし、勉強。
	PV3Dとかを使わない3D表現その1 
	Zソートとかもしてない。ただ点を打ってるだけです。
*/
package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	
	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
	public class simple3d_01 extends Sprite
	{
		private const FOCUS:Number=280;
		private const RADIUS:Number=100;
		private const N_POINT1:int=60;
		private const N_POINT2:int=100;
		private const CENTER_X:int=465 / 2;
		private const CENTER_Y:int=465 / 2;
		private const W:int=465;
		private const H:int=465;
		private const RADIAN:Number=Math.PI / 180;
		
		private var canvas:BitmapData;
		private var ary:Array;
		private var theta:Number=0;
		
		public function simple3d_01()
		{
			canvas=new BitmapData(465, 465, false, 0x000000);
			addChild(new Bitmap(canvas));
			ary=[];
			
			// 各点の初期位置を計算
			for(var i:int=0; i < N_POINT1; i++)
			{
				var theta1:Number=(360 / N_POINT1) * i * RADIAN;
				for(var j:int=0; j < N_POINT2; j++)
				{
					var theta2:Number=((180 / N_POINT2) * j - 90) * RADIAN;
					var xx:Number=RADIUS * Math.cos(theta2) * Math.sin(theta1);
					var yy:Number=RADIUS * Math.sin(theta2);
					var zz:Number=RADIUS * Math.cos(theta2) * Math.cos(theta1);
					var p:point3d=new point3d(xx, yy, zz);
					ary[i * N_POINT2 + j]=p;
				}
			}
			addEventListener(Event.ENTER_FRAME, onFrame);
		}
		
		private function onFrame(e:Event):void
		{
			theta+=1.0;
			canvas.fillRect(canvas.rect, 0x000000);
			canvas.lock();
			for(var i:int=0; i < N_POINT1; i++)
			{
				for(var j:int=0; j < N_POINT2; j++)
				{
					var p:point3d=ary[i * N_POINT2 + j] as point3d;
					
					// 回転行列で回転 (x軸回転とy軸回転の積を展開したもの)
					var tmpX:Number=p.x * Math.cos(theta * RADIAN) + p.y * Math.sin(theta * RADIAN) * Math.sin(theta * RADIAN) - p.z * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN);
					var tmpY:Number=p.y * Math.cos(theta * RADIAN) + p.z * Math.sin(theta * RADIAN);
					var tmpZ:Number=p.x * Math.sin(theta * RADIAN) - p.y * Math.sin(theta * RADIAN) * Math.cos(theta * RADIAN) + p.z * Math.cos(theta * RADIAN) * Math.cos(theta * RADIAN);
					
					// 3D→2D変換
					var scale:Number=FOCUS * 1.5 / (FOCUS - tmpZ);
					var xx:int=int(tmpX * scale) + CENTER_X;
					var yy:int=int(tmpY * scale) * (-1) + CENTER_Y;
					
					// 範囲内なら点を打つ
					if (xx >= 0 && yy >= 0 && xx < W && yy < H) canvas.setPixel(xx, yy, p.color);
				}
			}
			canvas.unlock();
		}
	}
}

class point3d
{
	public var x:Number;
	public var y:Number;
	public var z:Number;
	public var color:uint;
	
	public function point3d(x:Number=0, y:Number=0, z:Number=0)
	{
		this.x=x;
		this.y=y;
		this.z=z;
		color=Math.random() * 0x00ffff;
	}
}