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

forked from: ドロネー図(分割)

画面を適当にクリックすると3クリック以降、ポイントと線がひかれます。
線は交差すること無くひかれていきます

参照:
ドロネー図
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
/**
 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/9fRQ
 */

// forked from fumix's ドロネー図(分割)
/**
画面を適当にクリックすると3クリック以降、ポイントと線がひかれます。
線は交差すること無くひかれていきます

参照:
ドロネー図
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
*/
package {
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.events.MouseEvent;
	import flash.display.StageQuality;
	import flash.display.StageScaleMode;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;
    import flash.system.Security;
    import flash.display.StageAlign;
	[SWF(width = 465, height = 465, backgroundColor = 0x0, frameRate = 60)]

	public class Delaunay extends Sprite {

		//----------------------------------------
		//VARIABLES
		
		//点群
		private var _points : Array;
		//三角形の集まり
		private var _triangles : Array;
		//キャンバス
		private var _canvas : Sprite;
		//background
        private var _background:BitmapData;

		/*
		 * コンストラクタ
		 */
		public function Delaunay() {
			//Security.allowDomain("*");
            //Security.allowDomain("planet-ape.net");
            //Security.allowDomain("wonderfl.net");
            //Security.allowDomain("swf.wonderfl.net");
			//初期化
			addEventListener(Event.ADDED_TO_STAGE, _initialize);
		}

		/*
		 * 初期化
		 */
		private function _initialize(event : Event) : void {
			removeEventListener(Event.ADDED_TO_STAGE, _initialize);
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			stage.align = StageAlign.TOP_LEFT;
			
			var stageWidth : Number = stage.stageWidth;
			var stageHeight : Number = stage.stageHeight;
			//背景カラー
            _background = new BitmapData(stageWidth , stageHeight, false, 0x0);
            addChild(new Bitmap(_background));

			//ドロー用
			_canvas = addChild(new Sprite()) as Sprite;

			_points = new Array();
			_triangles = new Array();
			
			//ステージの大きさの三角形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 _updateHandler() : void {
			//if(mouseX<100)_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;
			var offset : Number = 0;
			g.clear();
			g.lineStyle(1, 0xffffff);
			
			//三角形群のループ
			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)
				){
				g.moveTo(tri.node0.point.x + offset, tri.node0.point.y + offset);
				g.lineTo(tri.node1.point.x + offset, tri.node1.point.y + offset);
				g.lineTo(tri.node2.point.x + offset, tri.node2.point.y + offset);
				g.lineTo(tri.node0.point.x + offset, tri.node0.point.y + offset);
				g.beginFill(0xFF0000);
				g.drawCircle(tri.node0.point.x + offset, tri.node0.point.y + offset, 3);
				g.drawCircle(tri.node1.point.x + offset, tri.node1.point.y + offset, 3);
				g.drawCircle(tri.node2.point.x + offset, tri.node2.point.y + offset, 3);
				g.endFill();					
				}
			}
		}

		/*
		 * 外接円の内か外か
		 */
		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 {
			_points.push(new Node(_points.length, mouseX, mouseY));

_interaction();_interaction();_interaction();
_updateHandler() 
		}
	}
}
class Triangle {
	private var _node0 : Node;
	private var _node1 : Node;
	private var _node2 : Node;
	
	public function Triangle(node0:Node,node1:Node,node2:Node):void {
		_node0 = node0;
		_node1 = node1;
		_node2 = node2;
	}
	
	public function get node0() : Node {
		return _node0;
	}
	
	public function get node1() : Node {
		return _node1;
	}
	
	public function get node2() : Node {
		return _node2;
	}
}
import flash.geom.Point;
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;
	}
}