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

クォータニオン練習

package 
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.filters.BlurFilter;
	import flash.filters.ColorMatrixFilter;
	
	[SWF(width="465", height="465", backgroundColor="0x0", frameRate="90")]
	public class TestQuaternion extends Sprite
	{
		private const L:uint = 465;
		private const N:uint = 10000;
		private const cameraZ:Number = -3.0;
		private const X0:Number = L / 2;
		private const Y0:Number = L / 2;
		private var particles:Array = [];
		private var dat:BitmapData;
		private var bm:Bitmap;
		private var qx:Quaternion = new Quaternion(0,1,0,0);
		private var qy:Quaternion = new Quaternion(0,0,1,0);
		private var qz:Quaternion = new Quaternion(0,0,0,1);
		private var lastX:Number;
		private var lastY:Number;
		public function  TestQuaternion() {
			dat = new BitmapData(L, L, false, 0);
			bm = new Bitmap(dat);
			for (var i:int = 0; i < N; i++) 
			{
				particles[i] = new Particle();
			}
			addChild(bm);
			filters = [new BlurFilter(2,2)];
			lastX = mouseX;
			lastY = mouseY;
			addEventListener(Event.ENTER_FRAME, loop);
		}
		private function loop(e:Event):void {
			update();
		}
		private function update():void {
			var dx:Number = mouseX - lastX;
			var dy:Number = mouseY - lastY;
			var dr:Number = Math.sqrt(dx * dx + dy * dy) / L;
			if(dr != 0){
				qx = qx.rotateV(dr, dy, -dx, 0);
				qy = qy.rotateV(dr, dy, -dx, 0);
				qz = qz.rotateV(dr, dy, -dx, 0);
			}
			lastX = mouseX;
			lastY = mouseY;
			dat.lock();
			dat.draw(this);
			var p:Particle;
			var _x:Number;
			var _y:Number;
			var _z:Number;
			var $x:Number;
			var $y:Number;
			var $z:Number;
			for each(p in particles) {
				_x = p.x * qx.x + p.y * qy.x + p.z * qz.x;
				_y = p.x * qx.y + p.y * qy.y + p.z * qz.y;
				_z = p.x * qx.z + p.y * qy.z + p.z * qz.z;
				$z = (_z - cameraZ) / L;
				$x = X0 + _x / $z;
				$y = Y0 + _y / $z;
				dat.setPixel($x, $y, p.color);
			}
			dat.unlock();
		}
	}
	
}

internal class  Quaternion
{
	public var w:Number;
	public var x:Number;
	public var y:Number;
	public var z:Number;
	public function Quaternion(w:Number = 0, x:Number = 0, y:Number = 0, z:Number = 0) {
		this.w = w;
		this.x = x;
		this.y = y;
		this.z = z;
	}
	
	public static function multiple(q1:Quaternion, q2:Quaternion):Quaternion {
		return new Quaternion(
			q1.w * q2.w - q1.x * q2.x - q1.y * q2.y - q1.z * q2.z,
			q1.w * q2.x + q1.x * q2.w + q1.y * q2.z - q1.z * q2.y,
			q1.w * q2.y - q1.x * q2.z + q1.y * q2.w + q1.z * q2.x,
			q1.w * q2.z + q1.x * q2.y - q1.y * q2.x + q1.z * q2.w
		);
	}

	public function rotateX(r:Number):Quaternion {
		var cos :Number = Math.cos(r);
		var sin :Number = Math.sin(r);
		return multiple(
			multiple(
				new Quaternion(cos, sin, 0, 0),
				this
			),
			new Quaternion (cos, -sin, 0,0)
		);
	}

	public function rotateY(r:Number):Quaternion {
		var cos :Number = Math.cos(r);
		var sin :Number = Math.sin(r);
		return multiple(
			multiple(
				new Quaternion(cos, 0, sin, 0),
				this
			),
			new Quaternion (cos, 0, -sin,0)
		);
	}

	public function rotateZ(r:Number):Quaternion {
		var cos :Number = Math.cos(r);
		var sin :Number = Math.sin(r);
		return multiple(
			multiple(
				new Quaternion(cos, 0, 0, sin),
				this
			),
			new Quaternion (cos, 0,0, -sin)
		);
	}
	
	public function rotateV(r:Number, x:Number, y:Number, z:Number):Quaternion {
		var cos :Number = Math.cos(r);
		var sin :Number = Math.sin(r)/Math.sqrt(x * x + y * y + z * z);
		x *= sin;
		y *= sin;
		z *= sin;
		return multiple(
			multiple(
				new Quaternion(cos, x, y, z),
				this
			),
			new Quaternion (cos, -x, -y, -z)
		);
	}
}

internal class Particle {
	
	public var x:Number;
	public var y:Number;
	public var z:Number;
	private var vx:Number;
	private var vy:Number;
	private var vz:Number;
	public var color:uint;
	
	public function Particle() {
		var r:Number = Math.random();
		var phi:Number = Math.PI * Math.random();
		var theta:Number = 2 * Math.PI * Math.random();
		x = r * Math.sin(phi)*Math.cos(theta);
		y = r * Math.sin(phi)*Math.sin(theta);
		z = r * Math.cos(phi);
		vx = 0;
		vy = 0;
		vz = 0;
		color = Math.random ()* 0xffffff;
	}
	public function update():void {
	}
}