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

Mathematics Sketch - center of gravity

多角形の重心の求め方。
一つの点を基点として三角形に分解して三角形の重心の平均を求める。

・三角形の重心
点(ax, ay), (bx, by) , (cx, cy)の重心(x, y)

x = (ax + bx + cx) / 3
y = (ay + by + cy) / 3
Get Adobe Flash player
by euakast 15 Feb 2011
/**
 * Copyright euakast ( http://wonderfl.net/user/euakast )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/wQFm
 */

package  
{
    import com.bit101.components.*;
    import flash.display.*;
    import flash.events.*;
    
    public class MathematicsSketch extends Sprite {
        
        private static const NUM_INITIAL_POINTS:int = 6;
        
        private var _sprites:Array;
        private var _points:Array;
        private var _data:Vector.<Number>;
        private var _commands:Vector.<int>;
        private var _centerLabel:Label;
        private var _center:Vec2d;
        
        public function MathematicsSketch() {
            if (stage) init();
            else addEventListener(Event.ADDED_TO_STAGE, init);
        }
        
        private function init(e:Event = null):void {
            addPoints(NUM_INITIAL_POINTS);
            drawInterface();
            addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        }
        
        private function addPoints(amt:int):void {
            if (_points && _points.length != 0) {
                removeAllPoints();
            }
            _data = new Vector.<Number>();
            _sprites = [];
            _points = [];
            var cx:Number = stage.stageWidth * 0.5;
            var cy:Number = stage.stageHeight * 0.5;
            var step:Number = (Math.PI * 2) / amt;
            for (var i:int = 0; i < amt; ++i) {
                var a:Number = step * i;
                var pos:Vec2d = new Vec2d(Math.cos(a) * Random.randint(50, 200) + cx, Math.sin(a) * Random.randint(50, 200) + cy);
                var p:PointSprite = new PointSprite(this, pos);
                _sprites.push(p);
                _points.push(pos);
            }
            _commands = makeCommands();
        }
        
        private function removeAllPoints():void {
            var l:int = _sprites.length;
            for (var i:int = 0; i < l; ++i) {
                var sprite:PointSprite = _sprites[i];
                removeChild(sprite);
            }
            _sprites = null;
            _points = null;
        }
        
        private function makeCommands():Vector.<int> {
            var commands:Vector.<int> = new Vector.<int>();
            commands.push(GraphicsPathCommand.MOVE_TO);
            var l:int = _points.length + 1;
            for (var i:int = 1; i < l; ++i) {
                commands.push(GraphicsPathCommand.LINE_TO);
            }
            return commands;
        }
        
        private function enterFrameHandler(e:Event):void {
            update();
            draw();
            _centerLabel.text = "CenterPoint: x = " + Math.floor(_center.x) + ", y = " + Math.floor(_center.y);
        }
        
        private function update():void {
            var count:int = 0;
            var l:int = _points.length;
            for (var i:int = 0; i < l; ++i) {
                var p:Vec2d = _points[i];
                _data[count] = p.x;
                _data[count + 1] = p.y;
                count += 2;
                if (i == l -1) {
                    p = _points[0];
                    _data[count] = p.x;
                    _data[count + 1] = p.y;
                }
            }
            _center = calcCenterPos(_points);
        }
        
        private function draw():void {
            graphics.clear();
            graphics.lineStyle(2.0);
            graphics.drawPath(_commands, _data);
            graphics.beginFill(0xFF0000);
            graphics.lineStyle(1, 0xFF0000);
            graphics.drawCircle(_center.x, _center.y, 6);
            graphics.endFill();
        }
        
        private function calcTriangleCenterPos(a:Vec2d, b:Vec2d, c:Vec2d):Vec2d {
            var v:Vec2d = a.add(b).add(c);
            return new Vec2d(v.x / 3, v.y / 3);
        }
        
        private function calcTrianbleArea(a:Vec2d, b:Vec2d, c:Vec2d):Number {
            var v1:Vec2d = b.sub(a);
            var v2:Vec2d = c.sub(a);
            var cross:Number = v2.cross(v1.normalized());
            return v1.length * cross * 0.5;
        }
        
        private function calcCenterPos(points:Array):Vec2d {
            var total:Number = 0;
            var tmp:Vec2d = new Vec2d();
            var a:Vec2d = points[0];
            var l:int = points.length - 1;
            for (var i:int = 1; i < l; ++i) {
                var b:Vec2d = points[i];
                var c:Vec2d = points[i + 1];
                var s:Number = calcTrianbleArea(a, b, c);
                var center:Vec2d = calcTriangleCenterPos(a, b, c);
                total += s;
                tmp.x += center.x * s;
                tmp.y += center.y * s;
            }
            return new Vec2d(tmp.x / total, tmp.y / total);
        }
        
        private function drawInterface():void {
            var vBox:VBox = new VBox(this, 10, 10);
            var fps:FPSMeter = new FPSMeter(vBox);
            var numericStepper:NumericStepper = new NumericStepper(vBox, 0, 0, function():void {
                addPoints(numericStepper.value);
            });
            numericStepper.minimum = 3;
            numericStepper.value = NUM_INITIAL_POINTS;
            _centerLabel = new Label(vBox);
        }
    }

}

import flash.display.*;
import flash.events.*;
class PointSprite extends Sprite {
    private var _pos:Vec2d;
    private var _radius:Number;
    public function PointSprite(parent:DisplayObjectContainer, pos:Vec2d, radius:Number = 6) {
        parent.addChild(this);
        this.pos = pos;
        this.radius = radius;
        buttonMode = true;
        draw();
        addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
    }
    private function mouseDownHandler(e:MouseEvent):void {
        startDrag();
        addEventListener(Event.ENTER_FRAME, enterFrameHandler);
        stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
    }
    private function mouseUpHandler(e:MouseEvent):void {
        stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
        removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
        stopDrag();
    }
    private function enterFrameHandler(e:Event):void {
        _pos.x = x;
        _pos.y = y;
    }
    private function draw():void {
        graphics.clear();
        graphics.beginFill(0x0);
        graphics.drawCircle(0, 0, _radius);
        graphics.endFill();
    }
    public function get pos():Vec2d { return _pos; }
    public function set pos(value:Vec2d):void { _pos = value; x = _pos.x; y = _pos.y; }
    public function get radius():Number { return _radius; }
    public function set radius(value:Number):void { _radius = value; }
}

class Vec2d {
    public var x:Number, y:Number;
    public function Vec2d(ax:Number = 0.0, ay:Number = 0.0) { x = ax; y = ay; }
    public function clone():Vec2d { return new Vec2d(x, y); }
    public function set(ax:Number, ay:Number):void { x = ax; y = ay; }
    public function get length():Number { return Math.sqrt(x * x + y * y); }
    public function set length(value:Number):void { var a:Number = angle; x = Math.cos(a) * value; y = Math.sin(a) * value; }
    public function get lengthSqrt():Number { return x * x + y * y; }
    public function get angle():Number { return Math.atan2(y, x); }
    public function normalize():void { var invS:Number = 1 / length; x *= invS; y *= invS; }
    public function normalized():Vec2d { var invS:Number = 1 / length; return new Vec2d(x * invS, y * invS); }
    public function add(rhs:Vec2d):Vec2d { return new Vec2d(x + rhs.x, y + rhs.y); }
    public function sub(rhs:Vec2d):Vec2d { return new Vec2d(x - rhs.x, y - rhs.y); }
    public function mul(rhs:Vec2d):Vec2d { return new Vec2d(x * rhs.x, y * rhs.y); }
    public function div(rhs:Vec2d):Vec2d { return new Vec2d(x / rhs.x, y / rhs.y); }
    public function dot(rhs:Vec2d):Number { return x * rhs.x + y * rhs.y; }
    public function cross(rhs:Vec2d):Number { return x * rhs.y - y * rhs.x; }
    public function scale(s:Number):Vec2d { return new Vec2d(x * s, y * s); }
    public function distance(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return Math.sqrt(dx * dx + dy * dy); }
    public function distanceSqrd(rhs:Vec2d):Number { var dx:Number = x - rhs.x; var dy:Number = y - rhs.y; return dx * dx + dy * dy; }
    public function rotate(angle:Number):void { var cosa:Number = Math.cos(angle); var sina:Number = Math.sin(angle); var rx:Number = x * cosa - y * sina; y = x * sina + y * cosa; x = rx; }
    public function truncate(max:Number):void { this.length = Math.min(max, this.length); }
}
class Random {
    public static function random(min:Number = 0, max:Number = NaN):Number {
        if (isNaN(max)) { max = min; min = 0; }
        return min + Math.random() * (max - min);
    }
    public static function randint(min:int = 0, max:int = NaN):int {
        if (isNaN(max)) { max = min; min = 0; }
        return min + Math.floor(Math.random() * (max - min + 1));
    }
}