In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

Gear

Gear simuration
Get Adobe Flash player
by flashrod 23 Dec 2008
/**
 * Copyright flashrod ( http://wonderfl.net/user/flashrod )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/z44m
 */

// Gear simuration
package {
    import flash.display.GradientType;
    import flash.display.Shape;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    public class Gear extends Sprite {
        private static const area:Rectangle = new Rectangle(0, 0, 465, 465);
        private var planes:Array = [];
        private var torque:Object;
        private var shafts:Array = [];
        private var displays:Array = [];
        public function Gear() {
            rebuild();
            stage.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {rebuild();});
            addEventListener(Event.ENTER_FRAME, function(e:Event):void {
                step();
                for each (var o:Object in displays) {
                    o.shape.rotation = 180 * o.gear.angle / Math.PI;
                }
            });
        }
        private function put(a:Array, p:Object, g0:Object, n0:int):void {
            if (n0 > 10) {
                var m:int = 1 + 4 * Math.random();
                var n:Array = [];
                var sum:Number = 0;
                for (var i:int = 0; i < m; ++i) {
                    var n2:int = n0 + n0 * Math.random();
                    n[i] = n2;
                    sum += n2;
                }
                var b:Array = [];
                var a2:Number = 2 * Math.PI * Math.random();
                for (i = 0; i < m; ++i) {
                    b[i] = (2 * Math.PI) * (a2 / sum);
                    a2 += n[i];
                }
                for (i = 0; i < m; ++i) {
                    var g2:Object = create_gear_mesh_with(g0, b[i], n[i]);
                    if (area.containsPoint(g2.center)) {
                        plane_add_gear(p, g2);
                        p.linkes.push({ tail:g0, head:g2 });
                        var s2:Shape = create_shape(g2, p.unit/4, Math.random() * 0xFFFFFF);
                        a.push({shape:s2, gear:g2});
                        put(a, p, g2, n0/2);
                    }
                }
            }
        }
        private function rebuild():void {
            var a:Array = [];
            var p1:Object = { unit:12, gears:[], linkes:[], table:[] };
            p1.unit = 8 + 8 * Math.random();
            planes.push(p1);
            var n0:int = 30 + 30 * Math.random();
            var p0:Point = new Point(area.width/2, area.height/2);
            var g0:Object = create_gear(p0, n0);
            plane_add_gear(p1, g0);
            var s0:Shape = create_shape(g0, p1.unit/4, Math.random() * 0xFFFFFF);
            a.push({shape:s0, gear:g0});
            torque = g0;
            put(a, p1, g0, n0);
            var p2:Object = { unit:12, gears:[], linkes:[], table:[] };
            p2.unit = p1.unit / 2;
            planes.push(p2);
            var g3:Object = a[int(Math.random() * a.length)].gear;
            var n4:int = 30 + 30 * Math.random();
            var p4:Point = g3.center;
            var g4:Object = create_gear(p4, n4);
            plane_add_gear(p2, g4);
            shafts.push({ tail:g3, head:g4 });
            var s4:Shape = create_shape(g4, p2.unit/4, Math.random() * 0xFFFFFF);
            shape_plot_mark(s4, 8);
            a.push({shape:s4, gear:g4});
            put(a, p2, g4, n4);
            for each (var o:Object in displays) {
                removeChild(o.shape);
            }
            displays = a;
            for each (o in displays) {
                addChild(o.shape);
            }
        }
        private function step():void {
            for each (var p:Object in planes) {
                plane_forEachGear(p, gear_begin);
            }
            gear_step(torque, 1/4);
            for each (p in planes) {
                plane_forEachGear(p, gear_commit);
            }
        }
        private function plane_add_gear(plane:Object, g:Object):void {
            g.parent = plane;
            g.id = plane.gears.length;
            plane.gears.push(g);
        }
        private function plane_get_links(plane:Object, g:Object):Array {
            var a:Array = [];
            for each (var link:Object in plane.linkes) {
                if (link_contains(link, g)) {
                    a.push(link);
                }
            }
            return a;
        }
        private function plane_links(plane:Object, g:Object):Array {
            var a:Array = plane.table[g.id];
            if (a == null) {
                a = plane_get_links(plane, g);
                plane.table[g.id] = a;
            }
            return a;
        }
        private function plane_get_shafts(g:Object):Array {
            var a:Array = [];
            for each (var link:Object in shafts) {
                if (link_contains(link, g)) {
                    a.push(link);
                }
            }
            return a;
        }
        private function plane_forEachGear(plane:Object, fn:Function):void {
            for each (var g:Object in plane.gears) {
                fn(g);
            }
        }
        private function create_gear(c:Point, n:int, a:Number=0):Object {
            return { parent:null, id:0, center: c, teeth: n, angle: a, next:0.0, visited:false };
        }
        private function create_gear_mesh_with(gear:Object, t:Number, n:Number):Object {
            var p:Point = gear_meshPoint(gear, t, n);
            var a:Number = gear_meshAngle(gear, t, n);
            return create_gear(p, n, a);
        }
        private function gear_meshPoint(gear:Object, t:Number, n:Number):Point {
            var r:Number = get_gear_radius(gear) + gear_toRadius(gear, n);
            return new Point(gear.center.x + r * Math.cos(t), gear.center.y + r * Math.sin(t));
        }
        private function gear_meshAngle(gear:Object, t:Number, n:Number):Number {
            var theta:Number = t - gear.angle;
            var m:Number = gear_angleToTeeth(gear, get_gear_radius(gear), theta);
            var phi:Number = gear_teethToAngle(gear, gear_toRadius(gear, n), m);
            return Math.PI + (gear.angle) + (theta + phi);
        }
        private function gear_begin(gear:Object):void {
            gear.visited = false;
            gear.next = 0;
        }
        private function gear_commit(gear:Object):void {
            gear.angle += gear.next * (2 * Math.PI / gear.teeth);
        }
        private function gear_step(gear:Object, v:Number):void {
            if (!gear.visited) {
                gear.visited = true;
                gear.next = v;
                for each (var link:Object in plane_links(gear.parent, gear)) {
                    var g:Object = link_other(link, gear);
                    gear_step(g, -v);
                }
                for each (link in plane_get_shafts(gear)) {
                    g = link_other(link, gear);
                    gear_step(g, gear_angleToTeeth(g, get_gear_radius(g), gear_teethToAngle(gear, get_gear_radius(gear), v)));
                }
            }
        }
        private function get_gear_radius(gear:Object):Number {
            return gear_toRadius(gear, gear.teeth);
        }
        private function gear_angleToTeeth(gear:Object, r:Number, a:Number):Number {
            return a * r / gear.parent.unit;
        }
        private function gear_teethToAngle(gear:Object, r:Number, n:Number):Number {
            return n * gear.parent.unit / r;
        }
        private function gear_toRadius(gear:Object, n:Number):Number {
            return n * gear.parent.unit / (2 * Math.PI);
        }
        private function create_shape(gear:Object, delta:Number=4, color:uint=0):Shape {
            var shape:Shape = new Shape();
            shape.x = gear.center.x;
            shape.y = gear.center.y;
            var r:int = get_gear_radius(gear);
            var teeth:int = gear.teeth;
            shape.graphics.lineStyle(1, color);
            shape.graphics.moveTo(r, 0);
            shape.graphics.beginGradientFill(GradientType.LINEAR, [color, color], [0, 1], [0, 255]);
            shape.graphics.lineStyle(0, color);
            var m1:Matrix = new Matrix();
            m1.rotate(-60 * 2 * Math.PI / 360);
            var m2:Matrix = new Matrix();
            m2.rotate(60 * 2 * Math.PI / 360);
            for (var t:int = 0; t < teeth; ++t) {
                var a1:Number = 2 * Math.PI * t/teeth;
                var a3:Number = 2 * Math.PI * (t+1)/teeth;
                var a2:Number = (a1 + a3) / 2;
                var p1:Point = new Point(r * Math.cos(a1), r * Math.sin(a1));
                var p2:Point = new Point(r * Math.cos(a2), r * Math.sin(a2));
                var p3:Point = new Point(r * Math.cos(a3), r * Math.sin(a3));
                var v12:Point = p2.subtract(p1);
                v12.normalize(delta);
                var q12:Point = p1.add(m1.transformPoint(v12));
                var v21:Point = p1.subtract(p2);
                v21.normalize(delta);
                var q21:Point = p2.add(m2.transformPoint(v21));
                shape.graphics.lineTo(q12.x, q12.y);
                shape.graphics.lineTo(q21.x, q21.y);
                shape.graphics.lineTo(p2.x, p2.y);
                var v23:Point = p3.subtract(p2);
                v23.normalize(delta);
                var q23:Point = p2.add(m2.transformPoint(v23));
                var v32:Point = p2.subtract(p3);
                v32.normalize(delta);
                var q32:Point = p3.add(m1.transformPoint(v32));
                shape.graphics.lineTo(q23.x, q23.y);
                shape.graphics.lineTo(q32.x, q32.y);
                shape.graphics.lineTo(p3.x, p3.y);
            }
            shape.graphics.endFill();
            return shape;
        }
        private function shape_plot_mark(shape:Shape, d:int):void {
            shape.graphics.drawCircle(0, 0, d);
            shape.graphics.moveTo(0, d);
            shape.graphics.lineTo(0, -d);
            shape.graphics.moveTo(d, 0);
            shape.graphics.lineTo(-d, 0);
        }
        private function link_contains(link:Object, g:Object):Boolean {
            return g == link.tail || g == link.head;
        }
        private function link_other(link:Object, g:Object):Object {
            return g == link.tail ? link.head : g == link.head ? link.tail : null;
        }
    }
}