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

ポリゴンmariroom

まいど同じ画像でスイマセン
mariroomの顔をポリゴン化しちゃいましょう(手動で)

作例:
http://movapic.com/fumix/pic/959331

参照:
ドロネー図
http://ja.wikipedia.org/wiki/ドロネー図
ドロネー図の作図方法
http://homepage3.nifty.com/endou/tips/04/tips33.htm
外接円
http://wonderfl.net/code/ad8b6c5010abdb44d3e34d3a7cd06a200b35175d
.fla2「YuruYurer」(195P)
http://www.amazon.co.jp/dp/4862670717
内接円を求める
http://homepage1.nifty.com/MADIA/delphi/delphi_bbs/200706/200706_07060041.html
ヘロンの公式
http://ja.wikipedia.org/wiki/ヘロンの公式
Get Adobe Flash player
by fumix 03 Sep 2010
/**
 * Copyright fumix ( http://wonderfl.net/user/fumix )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/giKT
 */

/**
まいど同じ画像でスイマセン
mariroomの顔をポリゴン化しちゃいましょう(手動で)

作例:
http://movapic.com/fumix/pic/959331

参照:
ドロネー図
http://ja.wikipedia.org/wiki/ドロネー図
ドロネー図の作図方法
http://homepage3.nifty.com/endou/tips/04/tips33.htm
外接円
http://wonderfl.net/code/ad8b6c5010abdb44d3e34d3a7cd06a200b35175d
.fla2「YuruYurer」(195P)
http://www.amazon.co.jp/dp/4862670717
内接円を求める
http://homepage1.nifty.com/MADIA/delphi/delphi_bbs/200706/200706_07060041.html
ヘロンの公式
http://ja.wikipedia.org/wiki/ヘロンの公式
 */
package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Graphics;
    import flash.display.Loader;
    import flash.display.Sprite;
    import flash.display.StageQuality;
    import flash.display.StageScaleMode;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.net.URLRequest;
    import flash.system.LoaderContext;

    [SWF(width = 465, height = 465, backgroundColor = 0xFFFFFF, frameRate = 60)]

    public class Delaunay extends Sprite {

        
        //----------------------------------------
        //CONST

        private const IMAGE_URL : String = "http://farm4.static.flickr.com/3639/3538831894_cca4aabd68.jpg";

        //----------------------------------------
        //VARIABLES
        
        //点群
        private var _points : Array;
        //三角形の集まり
        private var _triangles : Array;
        //キャンバス
        private var _canvas : Sprite;
        //画像
        private var _image : Bitmap;
        private var _imageData : BitmapData;

        //ボタン
        private var _renderButton : Button;
        private var _imageButton : Button;
        //フラグ
        private var _renderFlag : int;

        /*
         * コンストラクタ
         */
        public function Delaunay() {
            //初期化
            addEventListener(Event.ADDED_TO_STAGE, _initialize);
        }

        /*
         * 初期化
         */
        private function _initialize(event : Event) : void {
            removeEventListener(Event.ADDED_TO_STAGE, _initialize);

            stage.scaleMode = StageScaleMode.NO_SCALE;
            stage.quality = StageQuality.LOW;                
            
            //画像の読み込み
            var req : URLRequest = new URLRequest(IMAGE_URL);
            var loader : Loader = new Loader();
            loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadComplete);    
            loader.load(req, new LoaderContext(true));
        }

        /*
         * 画像読み込み終了後
         */
        private function loadComplete(event : Event) : void {

            event.target.removeEventListener(Event.COMPLETE, loadComplete);
            
            _image = event.target.loader.content as Bitmap;
            _imageData = _image.bitmapData;
            
            //画像を表示
            addChild(_image);
                    
            //ドロー用
            _canvas = addChild(new Sprite()) as Sprite;
            
            var stageWidth : Number = stage.stageWidth;
            var stageHeight : Number = stage.stageHeight;

            //ボタン
            _renderFlag = 0;
            _renderButton = new Button('render', 60);
            _renderButton.addEventListener(MouseEvent.CLICK, onRenderHandler);
            _renderButton.x = stageWidth - 60;
            addChild(_renderButton);

            _imageButton = new Button('image', 60);
            _imageButton.addEventListener(MouseEvent.CLICK, onImageHandler);
            _imageButton.x = stageWidth - 60;
            _imageButton.y = _renderButton.height + 1;
            addChild(_imageButton);

            _points = new Array();
            _triangles = new Array();
            //_points生成

            //ステージの大きさの三角形2つを用意
            _points.push(new Node(0, 0, 0));
            _points.push(new Node(1, stageWidth, 0));
            _points.push(new Node(2, stageWidth, stageHeight));
            _points.push(new Node(3, 0, stageHeight));
            _triangles.push(new Triangle(_points[0], _points[1], _points[2]));
            _triangles.push(new Triangle(_points[0], _points[2], _points[3]));

            addEventListener(Event.ENTER_FRAME, _updateHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP, _stageMouseUpHandler);
        }

        private function onImageHandler(event : MouseEvent) : void {
            _image.visible = !_image.visible;
        }

        private function onRenderHandler(event : MouseEvent) : void {
            _renderFlag ++;
            if(_renderFlag >2){
             _renderFlag = 0;   
            }
        }

        /*
         * アップデート
         */
        private function _updateHandler(event : Event) : void {
            _interaction();
            _draw();
        }

        /*
         * インタラクション
         */
        private function _interaction() : void {
            //一時保持の三角形群
            var localTriangles : Array = new Array();
            //辺
            var edges : Array;
            //多角形
            var polygon : Array;
            //ポイント群ループ
            for (var k : int = 4;k < _points.length;k++) {
                var node : Node = _points[k];
                localTriangles = new Array();
                edges = new Array();
            
                for (var i : String in _triangles) {
                    //点が外接円
                    var tri : Triangle = _triangles[i];
                    if(inOuterCircle(node.point.x, node.point.y, tri)) {
                        edges.push(new Edge(tri.node0, tri.node1));
                        edges.push(new Edge(tri.node1, tri.node2));
                        edges.push(new Edge(tri.node2, tri.node0));
                    } else {
                        localTriangles.push(tri);                        
                    }                
                }
                //edgesからpolygonを作る(重複辺の削除
                polygon = new Array();
                for (i in edges) {
                    var edge0 : Edge = edges[i];
                    //重複チェック
                    var flg : Boolean = false;
                    for (var j : String in polygon) {
                        var edge1 : Edge = polygon[j];
                        if(judgeEdges(edge0, edge1)) {
                            flg = true;
                            polygon.splice(j, 1);
                            break;                        
                        }
                    }
                    //データが存在しない場合は追加
                    if(!flg) polygon.push(edges[i]);
                }
                //polygonから三角形を作って挿入
                for (i in polygon) {
                    var tri1 : Triangle = new Triangle(polygon[i].node0, polygon[i].node1, node);
                    localTriangles.push(tri1);
                }
                if(localTriangles.length > 1) _triangles = localTriangles;
            }
        }

        /*
         * 同じ辺かどうかの判定
         */
        private function judgeEdges(edge : Edge, edge0 : Edge) : Boolean {            
            if(edge.node0.id == edge0.node0.id && edge.node1.id == edge0.node1.id) {
                return true;                
            }
            if(edge.node1.id == edge0.node0.id && edge.node0.id == edge0.node1.id) {
                return true;
            }
            return false;
        }

        /*
         * 描画
         */
        private function _draw() : void {
            var g : Graphics = _canvas.graphics;
            g.clear();
            
            //三角形群のループ
            for (var i : int = 0;i < _triangles.length;i++) {
                
                var tri : Triangle = _triangles[i];
                //四隅のポイントを含む三角形は描画しない
                if(!(tri.node0.id == 0 || tri.node1.id == 0 || tri.node2.id == 0 || tri.node0.id == 1 || tri.node1.id == 1 || tri.node2.id == 1 || tri.node0.id == 2 || tri.node1.id == 2 || tri.node2.id == 2 || tri.node0.id == 3 || tri.node1.id == 3 || tri.node2.id == 3)
                                ) {
                    if(_renderFlag == 0) {
                        _noRenderDraw(tri, g);
                    } else if(_renderFlag == 1) {
                        _renderDraw(tri, g);
                    } else {
                        _circleRenderDraw(tri, g);
                    }
                }
            }
        }

        private function _renderDraw(tri : Triangle,g : Graphics) : void {
            var fillColor : uint = _imageData.getPixel(tri.innerCirclePoint.x, tri.innerCirclePoint.y);
            g.beginFill(fillColor);
            g.moveTo(tri.node0.point.x, tri.node0.point.y);
            g.lineTo(tri.node1.point.x, tri.node1.point.y);
            g.lineTo(tri.node2.point.x, tri.node2.point.y);
            g.lineTo(tri.node0.point.x, tri.node0.point.y);
            g.endFill();
        }
        private function _circleRenderDraw(tri : Triangle,g : Graphics) : void {
            var fillColor : uint = _imageData.getPixel(tri.innerCirclePoint.x, tri.innerCirclePoint.y);
            g.beginFill(fillColor);
            g.drawCircle(tri.innerCirclePoint.x, tri.innerCirclePoint.y,tri.innerCircleRadius);
            g.endFill();
        }

        private function _noRenderDraw(tri : Triangle,g : Graphics) : void {
            g.lineStyle(1, 0xff0000);
            g.moveTo(tri.node0.point.x, tri.node0.point.y);
            g.lineTo(tri.node1.point.x, tri.node1.point.y);
            g.lineTo(tri.node2.point.x, tri.node2.point.y);
            g.lineTo(tri.node0.point.x, tri.node0.point.y);
        }

        /*
         * 外接円の内か外か
         */
        static function inOuterCircle(x : Number,y : Number,tri : Triangle) : Boolean {
            var node0 : Node = tri.node0;
            var node1 : Node = tri.node1;
            var node2 : Node = tri.node2;
            
            var d : Number = (node0.point.x * node0.point.x + node0.point.y * node0.point.y - x * x - y * y) * ((node1.point.x - x) * (node2.point.y - y) - (node2.point.x - x) * (node1.point.y - y)) + (node1.point.x * node1.point.x + node1.point.y * node1.point.y - x * x - y * y) * ((node2.point.x - x) * (node0.point.y - y) - (node2.point.y - y) * (node0.point.x - x)) + (node2.point.x * node2.point.x + node2.point.y * node2.point.y - x * x - y * y) * ((node0.point.x - x) * (node1.point.y - y) - (node0.point.y - y) * (node1.point.x - x));
            return ( (node1.point.x - node0.point.x) * (node2.point.y - node0.point.y) - (node1.point.y - node0.point.y) * (node2.point.x - node0.point.x) > 0 ) ? d > 0 : d <= 0;
        }

        /*
         * マウスクリック時
         */
        private function _stageMouseUpHandler(event : MouseEvent) : void {
            if((stage.stageWidth - 60) > mouseX) {
                _points.push(new Node(_points.length, mouseX, mouseY));
            }
        }
    }
}

import flash.display.Graphics;
import flash.display.Shape;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.geom.Point;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;

class Triangle {
    private var _node0 : Node;
    private var _node1 : Node;
    private var _node2 : Node;
    private var _innerCirclePoint : Point;
    private var _InnerCircleRadius : Number;

    public function Triangle(node0 : Node,node1 : Node,node2 : Node) : void {
        _node0 = node0;
        _node1 = node1;
        _node2 = node2;
        _innerCirclePoint = addInnerCirclePoint();
        _InnerCircleRadius = addInnerCircleRadius();
    }

    /*
     * 内接円の中心
     */
    private function addInnerCirclePoint() : Point {
        var x1 : Number = node0.point.x;
        var y1 : Number = node0.point.y;
        var x2 : Number = node1.point.x;
        var y2 : Number = node1.point.y;
        var x3 : Number = node2.point.x;
        var y3 : Number = node2.point.y;
        var a : Number = Math.sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2));
        var b : Number = Math.sqrt((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1));
        var c : Number = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
        var px : Number = (1 / (a + b + c)) * (a * x1 + b * x2 + c * x3);
        var py : Number = (1 / (a + b + c)) * (a * y1 + b * y2 + c * y3);
            
        return new Point(px, py);
    }

    /*
     * 内接円の半径
     */
    private function addInnerCircleRadius() : Number {
        var x1 : Number = node0.point.x;
        var y1 : Number = node0.point.y;
        var x2 : Number = node1.point.x;
        var y2 : Number = node1.point.y;
        var x3 : Number = node2.point.x;
        var y3 : Number = node2.point.y;
        var a : Number = Math.sqrt((x3 - x2) * (x3 - x2) + (y3 - y2) * (y3 - y2));
        var b : Number = Math.sqrt((x3 - x1) * (x3 - x1) + (y3 - y1) * (y3 - y1));
        var c : Number = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
        var s : Number = (a + b + c) * 0.5;
        var ss : Number = Math.sqrt(s * (s - a) * (s - b) * (s - c));
        var r : Number = 2 * ss / (a + b + c);
            
        return r;
    }

    public function get node0() : Node {
        return _node0;
    }

    public function get node1() : Node {
        return _node1;
    }

    public function get node2() : Node {
        return _node2;
    }

    public function get innerCirclePoint() : Point {
        return _innerCirclePoint;
    }

    public function get innerCircleRadius() : Number {
        return _InnerCircleRadius;
    }
}

class Node {
    private var _id : int;
    private var _point : Point;

    public function Node(id : int,x : Number,y : Number) {
        _id = id;
        _point = new Point(x, y);
    }

    public function get id() : int {
        return _id;
    }

    public function get point() : Point {
        return _point;
    }
}

class Edge {
    private var _node0 : Node;
    private var _node1 : Node;

    public function Edge(node0 : Node,node1 : Node) : void {
        _node0 = node0;
        _node1 = node1;
    }

    public function get node0() : Node {
        return _node0;
    }

    public function get node1() : Node {
        return _node1;
    }
}

class Button extends SimpleButton {

    public function Button(label : String, width : int = 0) : void {
        var up : Sprite = _buildImage(label, 0x0, width);
        var over : Sprite = _buildImage(label, 0x333333, width);
        var down : Sprite = _buildImage(label, 0x333333, width);
        down.y = 1;
        super(up, over, down, up);
    }

    private static function _buildImage(label : String, color : int, width : int = 0) : Sprite {
        var text : TextField = new TextField();
        text.defaultTextFormat = new TextFormat('Verdana', 10, 0xffffff, true, null, null, null, null, TextFormatAlign.CENTER);
        text.autoSize = TextFieldAutoSize.LEFT;
        text.selectable = false;
        text.text = label;
        text.x = (width - text.width) >> 1;
        text.y = 5;
        var base : Shape = new Shape();
        var g : Graphics = base.graphics;
        g.beginFill(color);
        g.drawRect(0, 0, width, text.height + 10);
        g.endFill();
        var sp : Sprite = new Sprite();
        sp.addChild(base);
        sp.addChild(text);
        return sp;
    }
}