<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init(false)"
>
<mx:Script>
<![CDATA[
import flash.display.BitmapData;
private static var planeWidth:int = 300;
private static var planeHeight:int = 300;
private static var xy:BitmapData;
private static var pointsABC:Array = new Array();
private static var lastX:int;
private static var lastY:int;
private static var opRuns:int = 0;
private static var unOpRuns:int = 0;
private static var opTimeSum:Number = 0;
private static var unOpTimeSum:Number = 0;
private function init(isRND:Boolean):void {
xy = new BitmapData(planeWidth, planeHeight, false, 0xFFFFFFFF);
pointsABC = new Array();
if( isRND ) {
for( var i:int = 0; i < 3; ++i ) {
pointsABC.push( rndDot(planeWidth, planeHeight) );
graphPoint( pointsABC[i][0], pointsABC[i][1], 0xFF0000 );
}
} else {
pointsABC.push( [planeWidth / 2, 0] );
pointsABC.push( [0, planeWidth] );
pointsABC.push( [planeWidth, planeHeight] );
for( var j:int = 0; j < 3; ++j ) {
graphPoint( pointsABC[j][0], pointsABC[j][1], 0xFF0000 );
}
}
lastX = rndDot(800, 800)[0];
lastY = rndDot(800, 800)[1];
xyPlane.source = new Bitmap( xy );
var startTime:Date = new Date();
var numIterations:int = int( iterations.value );
if( serpinski.selected ) {
if( optimized.selected ) {
opRuns ++;
makeSierpinskiOptimized( numIterations );
} else {
unOpRuns ++;
makeSierpinski( numIterations );
}
} else {
if( optimized.selected ) {
opRuns ++;
makeKoshOptimized( numIterations );
} else {
unOpRuns ++;
makeKosh( numIterations );
}
}
var endTime:Date = new Date();
var computeTime:int = endTime.getTime() - startTime.getTime();
runTimeDisplay.text = "compute time: " + String( computeTime / 1000 ) + " seconds";
if( optimized.selected ) {
opTimeSum += computeTime
avgOp.text = String( opTimeSum / opRuns );
} else {
unOpTimeSum += computeTime;
avgUnOp.text = String( unOpTimeSum / unOpRuns );
}
if( unOpRuns > 0 && opRuns > 0 ) {
perc.text = String( Number( avgOp.text ) / Number( avgUnOp.text ) );
}
}
private static function makeSierpinski(iterate:int):void {
for( var i:int = 0; i < iterate; ++i ) {
var rndNum:int = Math.floor( Math.random() * 3 );
var abcX:int = pointsABC[rndNum][0];
var abcY:int = pointsABC[rndNum][1];
var midX:int = ( lastX + abcX ) / 2;
var midY:int = ( lastY + abcY ) / 2;
graphPoint(midX, midY, 0x000000);
lastX = midX;
lastY = midY;
}
}
private static function makeSierpinskiOptimized(iterate:int):void {
for( var i:int = 0; i < iterate; ++i ) {
var rndNum:int = int( Math.random() * 3 );
var abcX:int = pointsABC[rndNum][0];
var abcY:int = pointsABC[rndNum][1];
var midX:int = ( lastX + abcX ) >> 1;
var midY:int = ( lastY + abcY ) >> 1;
graphPoint(midX, midY, 0x000000);
lastX = midX;
lastY = midY;
}
}
private static function makeKosh(iterate:int):void {
for( var i:int = 0; i < iterate; ++i ) {
var rndNum:int = Math.floor( Math.random() * 3 );
var abcX:int = pointsABC[rndNum][0];
var abcY:int = pointsABC[rndNum][1];
var midX:int = ( abcX - lastX ) / 2;
var midY:int = ( abcY - lastY ) / 2;
graphPoint(midX + ( planeWidth / 3 ), midY + ( planeHeight / 3 ), 0x000000);
lastX = midX;
lastY = midY;
}
}
private static function makeKoshOptimized(iterate:int):void {
var offsetW:int = int( planeWidth / 3 );
var offsetH:int = int( planeHeight / 3 );
for( var i:int = 0; i < iterate; ++i ) {
var rndNum:int = int( Math.random() * 3 );
var abcX:int = pointsABC[rndNum][0];
var abcY:int = pointsABC[rndNum][1];
var midX:int = ( abcX - lastX ) >> 1;
var midY:int = ( abcY - lastY ) >> 1;
graphPoint(midX + offsetW, midY + offsetH, 0x000000);
lastX = midX;
lastY = midY;
}
}
private static function rndDot(xMax:int, yMax:int):Array {
var xPoint:int = Math.floor( Math.random() * xMax );
var yPoint:int = Math.floor( Math.random() * yMax );
var points:Array = new Array();
points.push(xPoint, yPoint);
return points;
}
private static function graphPoint(x:int, y:int, c:int):void {
xy.setPixel(x, y, c);
}
]]>
</mx:Script>
<mx:Image
id="xyPlane"
x="5" y="80" width="300" height="300"/>
<mx:Button
label="random points"
x="2" y="2"
click="init(true)"/>
<mx:Button
label="perfect triangle"
x="118" y="2"
click="init(false)"/>
<mx:RadioButton
id="serpinski"
label="Serpinski"
x="264" y="3"
selected="true"
groupName="midPointType" />
<mx:RadioButton
id="kosh"
label="Kosh"
x="364" y="3"
groupName="midPointType" />
<mx:Label id="runTimeDisplay"
x="320" y="110"
text="compute time: "
width="200"/>
<mx:CheckBox
id="optimized"
x="320" y="80"
label="optimized"
selected="true"/>
<mx:Label x="320" y="140" text="ave. optimized time ="/>
<mx:Label x="320" y="160" text="avg. unoptimized time ="/>
<mx:Label x="320" y="180" text="avg. optimized / unoptimized ="/>
<mx:Label id="avgOp" x="505" y="140" width="60"/>
<mx:Label id="avgUnOp" x="505" y="160" width="60"/>
<mx:Label id="perc" x="505" y="180" width="82"/>
<mx:NumericStepper
id="iterations"
x="120" y="40"
width="100"
stepSize="10000"
minimum="10000" maximum="20000000"
value="1000000"/>
<mx:Label x="4" y="40" text="Iterations to run:"/>
</mx:Application>