Menger cut
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;
}
}
}