forked from: Interactive Pythagoras Tree with Growin' motion hacker_n23lv.. forked:0favorite:0lines:163license : All rights reserved modified : 2009-04-25 14:09:52 Embed Tweet // forked from broken's Interactive Pythagoras Tree with Growin' motion // forked from makc3d's Interactive Pythagoras Tree // Interactive Pythagoras Tree package { import flash.display.Graphics; import flash.display.Sprite; import flash.geom.Matrix; import flash.geom.Point; public class FlashTest extends Sprite { private var count:int = 0; private var left:Point = new Point; private var rotor:Matrix = new Matrix; private var s1:Point = new Point, s2:Point = new Point; // check out http://en.wikipedia.org/wiki/Pythagoras_tree private function ptree (at:Point, up:Point, g:Graphics):void { count += 1; // draw the square according to given position and direction left.x = -up.y; left.y = up.x; g.beginFill (0x31007*count); g.moveTo (at.x + up.x + left.x, at.y + up.y + left.y); g.lineTo (at.x + up.x - left.x, at.y + up.y - left.y); g.lineTo (at.x - up.x - left.x, at.y - up.y - left.y); g.lineTo (at.x - up.x + left.x, at.y - up.y + left.y); g.endFill (); // calculate radius var r:Point = rotor.transformPoint (up); // calculate half-sides s1.x = (r.x - left.x) * 0.5; s1.y = (r.y - left.y) * 0.5; s2.x = (r.x + left.x) * 0.5; s2.y = (r.y + left.y) * 0.5; // calculate directions var d1:Point = new Point (-s1.y, s1.x); var d2:Point = new Point (s2.y, -s2.x); // calculate positions of new squares var p1:Point = new Point (at.x + up.x + s2.x + d1.x, at.y + up.y + s2.y + d1.y); var p2:Point = new Point (at.x + up.x + s1.x + d2.x, at.y + up.y + s1.y + d2.y); // repeat twice if (count < _currentCount) { ptree (p1, d1, g); ptree (p2, d2, g); } if (count == _currentCount && count < _maxCount) { grow(p1, d1, up, 1, g); grow(p2, d2, up, -1, g); } count -= 1; } public function FlashTest() { addEventListener("enterFrame", onEnterFrame); } private function onEnterFrame (e:*):void { rotor.identity (); rotor.rotate (2.0 * (mouseX - stage.stageWidth * 0.5) / stage.stageWidth); graphics.clear (); ptree (new Point (230, 340), new Point (0, -40), graphics); doGrow(); } // private static const STATE_READY : int = 0; private static const STATE_SKEW1 : int = 1; private static const STATE_SKEW2 : int = 2; private static const STATE_SLIDE : int = 3; private var _state : int = STATE_READY; private var _step : int = 0; private var _maxStep : int = 10; private var _slide : Number = 0; private var _skew1 : Number = 0; private var _skew2 : Number = 0; private var _currentCount : int = 0; private var _maxCount : int = 10; private function doGrow() : void { switch(_state) { case STATE_READY : doReady(); break; case STATE_SKEW1 : doSkew1(); break; case STATE_SKEW2 : doSkew2(); break; case STATE_SLIDE : doSlide(); break; default : break; } } private function nextState() : void { _step = 0; switch(_state) { case STATE_READY : _state = STATE_SKEW1; break; case STATE_SKEW1 : _state = STATE_SKEW2; break; case STATE_SKEW2 : _state = STATE_SLIDE; break; case STATE_SLIDE : _state = STATE_READY; break; default : break; } } private function doReady() : void { // reset all _skew1 = 0; _skew2 = 0; _slide = 0; if (_currentCount < _maxCount) { _currentCount++; nextState(); } } private function doSkew1() : void { _skew1 = _step / _maxStep; if (++_step > _maxStep) { nextState(); } } private function doSkew2() : void { _skew2 = _step / _maxStep; if (++_step > _maxStep) { nextState(); } } private function doSlide() : void { _slide = _step / _maxStep; if (++_step > _maxStep) { nextState(); } } private function grow( p : Point, d : Point, up : Point, dir : Number, g : Graphics ) : void { var l_d : Number = Math.sqrt(d.x * d.x + d.y * d.y); var l_up : Number = Math.sqrt(up.x * up.x + up.y * up.y - l_d * l_d); var l : Point = new Point(-d.y, d.x); var pd : Point = new Point(p.x + d.x, p.y + d.y); var pl : Point = new Point(p.x + l.x, p.y + l.y); var norm : Matrix = new Matrix(); norm.concat(new Matrix(l.x, d.x, l.y, d.y) ); norm.translate(p.x, p.y); var m : Matrix = new Matrix(); // normalize norm.invert(); m.concat(norm); // slide m.translate(0, -2 * (1 - _slide) ); // skew-2 m.translate(0, 1); m.concat(new Matrix(1, 0, -l_up / l_d * dir * (1 - _skew2), 1) ); m.translate(0, -1); // skew-1 var t : Number = Math.atan(l_up / l_d); m.translate(-1 * dir, 1); m.rotate(-t * dir); m.concat(new Matrix(1, l_up / l_d * dir * (1 - _skew1), 0, 1) ); m.rotate(t * dir); m.translate(dir, -1); // restore norm.invert(); m.concat(norm); p = m.transformPoint(p); pd = m.transformPoint(pd); pl = m.transformPoint(pl); d = new Point(pd.x - p.x, pd.y - p.y); l = new Point(pl.x - p.x, pl.y - p.y); g.beginFill(0x00ff99, 0.5); g.moveTo (p.x + d.x + l.x, p.y + d.y + l.y); g.lineTo (p.x + d.x - l.x, p.y + d.y - l.y); g.lineTo (p.x - d.x - l.x, p.y - d.y - l.y); g.lineTo (p.x - d.x + l.x, p.y - d.y + l.y); g.endFill (); } } } Code Fullscreen Preview Fullscreen Point Math.atan Math.sqrt concat graphics mouseX addEventListener Sprite int Number