Forked from: sebleedelisle's flash on 2009-5-30 diff:170 forked from: flash on 2009-5-30 lab9 forked:0favorite:0lines:166license : MIT License modified : 2009-05-31 22:28:22 Embed Tweet package { import flash.display.Graphics; import flash.display.Sprite; import flash.events.MouseEvent; import flash.geom.Point; import flash.geom.Rectangle; import flash.text.TextField; import flash.text.TextFormat; import flash.utils.getTimer; [SWF(frameRate="100", backgroundColor="0x000000", width="500", height="500")] public class TriangleSpeedTest2 extends Sprite { public var outputText : TextField; public function TriangleSpeedTest2() { super(); outputText = new TextField(); x = y = 250; outputText.defaultTextFormat = new TextFormat("Arial"); outputText.textColor = 0xffffff; outputText.text = "Click to start test"; outputText.x = outputText.y = -250; outputText.width = 500; addChild(outputText); stage.addEventListener(MouseEvent.MOUSE_DOWN, startTest); } // I'm thinking that storing these values as properties rather than declaring them as local vars // should be faster... private var x0 : Number; private var y0 : Number; private var x1 : Number; private var y1 : Number; private var x2 : Number; private var y2 : Number; private var l : Number; private var r : Number; private var t : Number; private var b : Number; private var t0 : int; private var t1 : int; private var t2 : int; private var s : Number private var lm0 : Number private var lm1 : Number private var lm2 : Number private var rm0 : Number private var rm1 : Number private var rm2 : Number private var b0 :int; private var b1 :int; private var b2 :int; private var i0 :int; private var i1 :int; private var i2 :int; private var top_intersection:Number ; private var bottom_intersection : Number; private var toptrianglepoint : Number; private var bottomtrianglepoint : Number; private var m: Number; private var c : Number private var m0: Number; private var c0 : Number private var m1: Number; private var c1 : Number private var m2: Number; private var c2 : Number // THESE ARE THE TWO FUNCTIONS YOU CAN OPTIMISE. // I realise that you could inline the lineRectangleIntersect method, but I'd rather not do that just yet... // I'm looking for maths/logic improvements. public function triangleTest(rect:Rectangle, vertex0:Point, vertex1:Point, vertex2:Point ) : Boolean { // YOU MUST LEAVE THESE DECLARATIONS; they simulate necessary data exchange within PV3D l = rect.left; r = rect.right; t = rect.top; b = rect.bottom; x0 = vertex0.x; y0 = vertex0.y; x1 = vertex1.x; y1 = vertex1.y; x2 = vertex2.x; y2 = vertex2.y; b0 = int(x0 > l) | int(y0 > t) << 1 | int (x0 > r) << 2 | int (y0 > b) << 3; if (b0 == 3) return true; b1 = int(x1 > l) | int(y1 > t) << 1 | int (x1 > r) << 2 | int (y1 > b) << 3; if (b1 == 3) return true; b2 = int(x2 > l) | int(y2 > t) << 1 | int (x2 > r) << 2 | int (y2 > b) << 3; if (b2 == 3) return true; i0 = b0 ^ b1 if (i0 != 0) { m = (y1-y0) / (x1-x0); c = y0 -(m * x0); if (Boolean(i0 & 1)) { s = m * l + c; if ( s > t && s < b) return true; } if (Boolean(i0 & 2)) { s = (t - c) / m; if ( s > l && s < r) return true; } if (Boolean(i0 & 4)) { s = m * r + c; if ( s > t && s < b) return true; } if (Boolean(i0 & 8)) { s = (b - c) / m; if ( s > l && s < r) return true; } } i1 = b1 ^ b2 if (i1 != 0) { m = (y2-y1) / (x2-x1); c = y1 -(m * x1); if (Boolean(i1 & 1)) { s = m * l + c; if ( s > t && s < b) return true; } if (Boolean(i1 & 2)) { s = (t - c) / m; if ( s > l && s < r) return true; } if (Boolean(i1 & 4)) { s = m * r + c; if ( s > t && s < b) return true; } if (Boolean(i1 & 8)) { s = (b - c) / m; if ( s > l && s < r) return true; } } i2 = b0 ^ b2 if (i2 != 0) { m = (y2-y0) / (x2-x0); c = y0 -(m * x0); if (Boolean(i2 & 1)) { s = m * l + c; if ( s > t && s < b) return true; } if (Boolean(i2 & 2)) { s = (t - c) / m; if ( s > l && s < r) return true; } if (Boolean(i2 & 4)) { s = m * r + c; if ( s > t && s < b) return true; } if (Boolean(i2 & 8)) { s = (b - c) / m; if ( s > l && s < r) return true; } } return false; } public function startTest(e:MouseEvent = null) : void { var g : Graphics = graphics; g.clear(); var cullingRect : Rectangle = new Rectangle(-100,-75,200,150); var iterations : int = 100000; var timerIntersecting : int = 0 ; var timerNotIntersecting : int = 0 ; var intersectCount : int = 0; var v0 : Point = new Point(); var v1 : Point = new Point(); var v2 : Point = new Point(); var i : int = iterations; while(--i>-1) { v0.x = Math.random()*400 - 200; v0.y = Math.random()*400 - 200; v1.x = v0.x+ (Math.random()*300 -150); v1.y = v0.y+ (Math.random()*300 -150); v2.x = v0.x+ (Math.random()*300 -150); v2.y = v0.y+ (Math.random()*300 -150); var startTimer : int = getTimer(); var intersecting : Boolean = triangleTest(cullingRect, v0, v1, v2); if(intersecting) { timerIntersecting += (getTimer() - startTimer); intersectCount++; } else { timerNotIntersecting += (getTimer() - startTimer); } if(i<300) { g.lineStyle(0,0x000000); g.beginFill(intersecting ? 0x006600 : 0x660000,0.5); g.moveTo(x0,y0); g.lineTo(x1,y1); g.lineTo(x2,y2); g.lineTo(x0,y0); g.endFill(); } } g.lineStyle(0,0xffffff,0.5); g.drawRect(cullingRect.x, cullingRect.y, cullingRect.width, cullingRect.height); outputText.text = "Average time per triangle : "+(timerIntersecting+timerNotIntersecting)/iterations; outputText.appendText("\nAverage time per intersecting triangle : "+(timerIntersecting)/intersectCount); outputText.appendText("\nAverage time per non-intersecting triangle : "+(timerNotIntersecting)/(iterations-intersectCount)); } } } Code Fullscreen Preview Fullscreen Boolean Rectangle top bottom right left graphics MouseEvent.MOUSE_DOWN width height text MouseEvent addEventListener TextFormat addChild Math.random Sprite int Number