Beautifl - Flash Gallery

Thumbnail : Menger cut
Menger cut
makc3d 2011-02-21 see code comments

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

package {
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.geom.Vector3D;
	/**
	 * Intersection of 3D menger sponge by random plane (hard way).
	 * @author makc
	 */
	public class Menger extends Sprite {
		private var canvas:BitmapData;
		public function Menger () {
			canvas = new BitmapData (465, 465, false, 0);
			graphics.beginBitmapFill (canvas);
			graphics.drawRect (0, 0, 465, 465);
			click ();
			stage.addEventListener ("click", click);
		}
		private function click (e:*= null):void {
			var n:Vector3D = new Vector3D (
				Math.random () - Math.random (),
				Math.random () - Math.random (),
				Math.random () - Math.random ()
			);
			if (e == null) {
				n.x = 1;
				n.y = 1;
				n.z = 1;
			}
			n.normalize ();

			var U:Vector3D = new Vector3D (0, -n.z, n.y); U.normalize ();
			var V:Vector3D = n.crossProduct (U);

			canvas.fillRect (canvas.rect, 0);
			canvas.lock ();
			for (var i:int = -232; i < 232; i++)
			for (var j:int = -232; j < 232; j++) {
				var u:Number = i / 300;
				var v:Number = j / 300;
				if (hitTestMenger3D (u * U.x + v * V.x, u * U.y + v * V.y, u * U.z + v * V.z)) {
					canvas.setPixel (232 + i, 232 + j, 0xFFFFFF);
				}
			}
			canvas.unlock ();
		}
		private function hitTestMenger3D (x:Number, y:Number, z:Number):Boolean {
			// Menger sponge hittest code by Daniel White
			// http://www.fractalforums.com/3d-fractal-generation/revenge-of-the-half-eaten-menger-sponge/
			x += 0.5; y += 0.5; z += 0.5;
			if ((x<0)||(x>1)||(y<0)||(y>1)||(z<0)||(z>1)) return false;
			var p:Number = 3;
			for (var m:int = 1; m < 5 /* order */; m++) {
				var xa:Number = x*p - 3 * int (x*p / 3);
				var ya:Number = y*p - 3 * int (y*p / 3);
				var za:Number = z*p - 3 * int (z*p / 3);
				if (/* any two coordinates */
					((xa > 1.0) && (xa < 2.0)   &&   (ya > 1.0) && (ya < 2.0)) ||
					((ya > 1.0) && (ya < 2.0)   &&   (za > 1.0) && (za < 2.0)) ||
					((xa > 1.0) && (xa < 2.0)   &&   (za > 1.0) && (za < 2.0))
					) return false;
				p *= 3;
			}
			return true;
		}
	}
}