[BreakTime] forked from: ドロネー図(分割)
BreakTime
* @author Masayuki Komatsu / sekiryou.com
* http://twitter.com/sekiryou_com
/**
* Copyright sekiryou ( http://wonderfl.net/user/sekiryou )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/jvG3
*/
// forked from fumix's ドロネー図(分割)
/**
* BreakTime
* @author Masayuki Komatsu / sekiryou.com
* http://twitter.com/sekiryou_com
*/
package {
import flash.display.*;
import flash.events.*;
import flash.text.*;
import flash.geom.*;
import flash.filters.GlowFilter;
[SWF(width = 465, height = 465, backgroundColor = 0x0, frameRate = 30)]
public class BreakTime extends Sprite {
private const STAGE_WIDTH:uint = 465;
private const STAGE_HEIGHT:uint = 465;
private const STAGE_CENTER_X:Number = STAGE_WIDTH * 0.5;
private const STAGE_CENTER_Y:Number = STAGE_HEIGHT * 0.5;
private var projection:PerspectiveProjection;
private var projectionMatrix3D:Matrix3D;
private var mtx3D:Matrix3D = new Matrix3D();
private var world:Sprite;
private var panels:Vector.<Delaunay> = new Vector.<Delaunay>(60, false);
private var colons:Vector.<Delaunay> = new Vector.<Delaunay>(2, false);
private var expTime:Vector.<uint> = new Vector.<uint>(6, false);
private var expPosX:Vector.<Number> = new Vector.<Number>(8, false);
private var expPosY:Number = -100;
public function BreakTime() {
addChild(new Bitmap (new BitmapData (STAGE_WIDTH, STAGE_HEIGHT, false, 0x000000)));
projection = new PerspectiveProjection();
projection.fieldOfView = 60;
projectionMatrix3D = projection.toMatrix3D();
imageGenerater();
world = new Sprite();
world.x = STAGE_CENTER_X;
world.y = STAGE_CENTER_Y;
addChild(world);
const offset:uint = 60;
expPosX = Vector.<Number>([-340 - offset, -220 - offset, -60 - offset, 60 - offset, 220 - offset, 340 - offset, -140 - offset, 140 - offset]);
expTime = digitDivide();
for (var i:int = 0; i < 6; i++) {
for (var j:int = 0; j < 10; j++) {
var tagNum:uint = i * 10 + j;
panels[tagNum] = new Delaunay(60, 120, expPosX[i], expPosY, imgs[j]);
world.addChild(panels[tagNum]);
}
tagNum = i * 10 + expTime[i];
panels[tagNum].show();
}
for ( i = 0; i < 2; i++) {
var colon:Delaunay = new Delaunay(60, 120, expPosX[i+6], expPosY, imgs[10]);
world.addChild(colon);
colon.show();
colons[i] = colon;
}
addEventListener(Event.ENTER_FRAME, onEnterFrameHandler);
}
private var imgs:Vector.<BitmapData>;
private function imageGenerater():void {
imgs = new Vector.<BitmapData>();
var tf:TextFormat = new TextFormat();
tf.font = "Verdana";
tf.size = 160;
tf.align = TextFormatAlign.CENTER;
var txt:TextField = new TextField();
txt.defaultTextFormat = tf;
txt.textColor = 0x0099CC;
txt.type = TextFieldType.DYNAMIC;
txt.autoSize = TextFieldAutoSize.LEFT;
txt.filters = [new GlowFilter( 0x0099CC, 0.6, 4, 4, 2, 4 )];
for (var i:int = 0; i < 10; i++) {
txt.text = String(i);
var bmd:BitmapData = new BitmapData(txt.width, txt.height, true, 0x00000000);
bmd.draw(txt);
imgs.push(bmd);
}
txt.text = ":";
bmd = new BitmapData(txt.width, txt.height, true, 0x00000000);
bmd.draw(txt);
imgs.push(bmd);
}
private function digitDivide():Vector.<uint> {
var nowDate:Date = new Date();
var hour:uint = nowDate.getHours();
var min:uint = nowDate.getMinutes();
var sec:uint = nowDate.getSeconds();
return Vector.<uint>([int(hour / 10), hour - int(hour / 10) * 10, int(min / 10), min - int(min / 10) * 10, int(sec / 10), sec - int(sec / 10) * 10]);
}
private var cnt:Number = 1;
private function onEnterFrameHandler(e:Event):void {
var posX:Number = 0;
var posY:Number = (Math.sin(cnt * 3) + 1) / 2 * 200 - 100;
var posZ:Number = (Math.sin(cnt * -2) + 1) / 2 * 200;
var rotX:Number = 0;
var rotY:Number = Math.sin(cnt) * 60;
var rotZ:Number = 0;
cnt += 0.004;
var offsetZ:Number = 880;
mtx3D.identity();
mtx3D.appendRotation(rotX, Vector3D.X_AXIS);
mtx3D.appendRotation(rotY, Vector3D.Y_AXIS);
mtx3D.appendRotation(rotZ, Vector3D.Z_AXIS);
mtx3D.appendTranslation(posX, posY, posZ + offsetZ);
mtx3D.append(projectionMatrix3D);
bugfix(mtx3D);
var nds:Vector.<uint> = digitDivide();
for (var i:int = 0; i < 6; i++) {
var tagNum:uint = i * 10 + expTime[i];
if (expTime[i] != nds[i]) {
panels[tagNum].preCrash(5-i, 12);
expTime[i] = nds[i];
tagNum = i * 10 + expTime[i];
world.addChild(panels[tagNum]);
panels[tagNum].show();
}
for (var j:int = 0; j < 10; j++) {
if (panels[int(i * 10 + j)].isVisible) {
panels[int(i * 10 + j)].draw(mtx3D);
}
}
}
colons[0].draw(mtx3D);
colons[1].draw(mtx3D);
}
private function bugfix(matrix:Matrix3D):void {
var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
m1.append( m2 );
if (m1.rawData[15] == 20) {
var rawData:Vector.<Number> = matrix.rawData;
rawData[15] /= 20;
matrix.rawData = rawData;
}
}
}
}
/**
画面を適当にクリックすると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
*/
import flash.display.BitmapData;
import flash.display.Graphics;
import flash.display.Shape;
import flash.events.Event;
import flash.utils.getTimer;
import flash.geom.*;
class Delaunay extends Shape {
//----------------------------------------
//VARIABLES
//点群
private var _points:Vector.<Node> = new Vector.<Node>();
//三角形の集まり
private var _triangles:Vector.<Triangle> = new Vector.<Triangle>();
private var _sx:Number;
private var _sy:Number;
private var _ox:Number;
private var _oy:Number;
private var _img:BitmapData;
private var _isVisible:Boolean;
public function get isVisible():Boolean { return _isVisible; }
/*
* コンストラクタ
*/
public function Delaunay(sx:Number, sy:Number, ox:Number, oy:Number, img:BitmapData) {
_isVisible = false;
_sx = sx;
_sy = sy;
_ox = ox;
_oy = oy;
_img = img;
}
public function show():void {
_isVisible = true;
_points = Vector.<Node>([new Node(0, 0, 0), new Node(1, _sx, 0), new Node(2, _sx, _sy), new Node(3, 0, _sy)]);
_triangles = Vector.<Triangle>([new Triangle(_points[0], _points[1], _points[2]), new Triangle(_points[0], _points[2], _points[3])]);
_triangles[0].px = _ox;
_triangles[0].py = _oy;
_triangles[1].px = _ox;
_triangles[1].py = _oy;
alpha = 0;
addEventListener(
Event.ENTER_FRAME,
function():void {
alpha += 0.05
if (alpha > 1) {
removeEventListener(Event.ENTER_FRAME, arguments.callee);
}
}
);
}
private var waitTime:uint;
private var startTime:Number;
public function preCrash(wait:uint, partition:uint):void {
waitTime = wait * 200;
startTime = getTimer();
for (var k:int = 0; k < partition; k++) {
_points.push(new Node(_points.length, Math.random() * _sx, Math.random() * _sy));
_interaction();
}
addEventListener(Event.ENTER_FRAME, crash);
}
private function crash(e:Event = null):void {
var vanishTime:Number = 2000;
if (getTimer() - startTime > waitTime) {
for (var i : int = 0; i < _triangles.length; i++) {
var tri:Triangle = _triangles[i];
tri.rx += tri.tx;
tri.ry += tri.ty;
tri.rz += tri.tz;
tri.vy += 0.4;
tri.px += tri.vx;
tri.py += tri.vy;
tri.pz += tri.vz;
}
if (getTimer() - startTime > waitTime + vanishTime) {
_isVisible = false;
removeEventListener(Event.ENTER_FRAME, crash);
parent.removeChild(this);
}
}
}
private var mtx3D:Matrix3D = new Matrix3D();
public function draw(display3D:Matrix3D):void {
var panelVerts:Vector.<Number> = new Vector.<Number>();
var projectedVerts:Vector.<Number> = new Vector.<Number>();
var uvts:Vector.<Number> = new Vector.<Number>();
for (var i:int = 0; i < _triangles.length; i++) {
var tri:Triangle = _triangles[i];
for (var j : int = 0; j < 3; j++) {
var tmpNode:Node = tri["node" + j];
var tmpVector3D:Vector3D = new Vector3D(tmpNode.point.x, tmpNode.point.y, 0);
mtx3D.identity();
mtx3D.appendTranslation( -tri.centerOfGravity.x, -tri.centerOfGravity.y, 0);
mtx3D.appendRotation(tri.rx, Vector3D.X_AXIS);
mtx3D.appendRotation(tri.ry, Vector3D.Y_AXIS);
mtx3D.appendRotation(tri.rz, Vector3D.Z_AXIS);
mtx3D.appendTranslation(tri.centerOfGravity.x, tri.centerOfGravity.y, 0);
mtx3D.appendTranslation(tri.px, tri.py, tri.pz);
bugfix(mtx3D);
var newVector3D:Vector3D = mtx3D.transformVector(tmpVector3D);
panelVerts.push(tmpNode.point.x + newVector3D.x, tmpNode.point.y + newVector3D.y, newVector3D.z);
}
uvts.push(tri.node0.point.x / _sx, tri.node0.point.y / _sy, null, tri.node1.point.x / _sx, tri.node1.point.y / _sy, null, tri.node2.point.x / _sx, tri.node2.point.y / _sy, null);
}
Utils3D.projectVectors(display3D, panelVerts, projectedVerts, uvts);
var g:Graphics = graphics;
g.clear();
g.beginBitmapFill(_img);
g.drawTriangles(projectedVerts, null, uvts);
g.endFill();
}
private function bugfix(matrix:Matrix3D):void {
var m1:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0]));
var m2:Matrix3D = new Matrix3D(Vector.<Number>([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0]));
m1.append( m2 );
if (m1.rawData[15] == 20) {
var rawData:Vector.<Number> = matrix.rawData;
rawData[15] /= 20;
matrix.rawData = rawData;
}
}
/*
* インタラクション
*/
private function _interaction() : void {
//一時保持の三角形群
var localTriangles:Vector.<Triangle> = new Vector.<Triangle>();
//辺
var edges:Vector.<Edge>;
//多角形
var polygon:Vector.<Edge>;
//ポイント群ループ
for (var k : int = 4;k < _points.length;k++) {
var node : Node = _points[k];
localTriangles = new Vector.<Triangle>();
edges = new Vector.<Edge>();
for (var i : String in _triangles) {
//点が外接円
var tri : Triangle = _triangles[i];
tri.px = _ox;
tri.py = _oy;
if(inOuterCircle(node.point.x, node.point.y, tri)) { //*ポイントが外接円の中なら三角の辺を一時変数edgesへ代入*/
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へ代入*/
localTriangles.push(tri);
}
}
//edgesからpolygonを作る(重複辺の削除
polygon = new Vector.<Edge>();
for (i in edges) {
var edge0 : Edge = edges[i];
//重複チェック0
var flg : Boolean = false;
for (var j:String in polygon) {
var edge1 : Edge = polygon[j];
if(judgeEdges(edge0, edge1)) {
flg = true;
polygon.splice(int(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);
tri1.px = _ox;
tri1.py = _oy;
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;
}
/*
* 外接円の内か外か
*/
public 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;
}
}
import flash.geom.Point;
class Triangle {
private var _node0 : Node;
private var _node1 : Node;
private var _node2 : Node;
private var _centerOfGravity:Point;
private var _px:Number = 0;
private var _py:Number = 0;
private var _pz:Number = 0;
private var _vx:Number = Math.random() * 16.0 - 8.0;
private var _vy:Number = Math.random() * 16.0 - 8.0;
private var _vz:Number = Math.random() * 16.0 - 8.0;
private var _rx:Number = 0;
private var _ry:Number = 0;
private var _rz:Number = 0;
private var _tx:Number = Math.random() * 8.0 - 4.0;
private var _ty:Number = Math.random() * 8.0 - 4.0;
private var _tz:Number = Math.random() * 8.0 - 4.0;
public function Triangle(node0:Node,node1:Node,node2:Node):void {
_node0 = node0;
_node1 = node1;
_node2 = node2;
centerOfGravity = new Point((node0.point.x + node1.point.x + node2.point.x) / 3, (node0.point.y + node1.point.y + node2.point.y) / 3);
}
public function get node0() : Node {
return _node0;
}
public function get node1() : Node {
return _node1;
}
public function get node2() : Node {
return _node2;
}
public function get centerOfGravity():Point { return _centerOfGravity; }
public function get px():Number { return _px; }
public function get py():Number { return _py; }
public function get pz():Number { return _pz; }
public function get vx():Number { return _vx; }
public function get vy():Number { return _vy; }
public function get vz():Number { return _vz; }
public function get rx():Number { return _rx; }
public function get ry():Number { return _ry; }
public function get rz():Number { return _rz; }
public function get tx():Number { return _tx; }
public function get ty():Number { return _ty; }
public function get tz():Number { return _tz; }
public function set centerOfGravity(value:Point):void { _centerOfGravity = value; }
public function set px(value:Number):void { _px = value; }
public function set py(value:Number):void { _py = value; }
public function set pz(value:Number):void { _pz = value; }
public function set vx(value:Number):void { _vx = value; }
public function set vy(value:Number):void { _vy = value; }
public function set vz(value:Number):void { _vz = value; }
public function set rx(value:Number):void { _rx = value; }
public function set ry(value:Number):void { _ry = value; }
public function set rz(value:Number):void { _rz = value; }
public function set tx(value:Number):void { _tx = value; }
public function set ty(value:Number):void { _ty = value; }
public function set tz(value:Number):void { _tz = value; }
}
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;
}
}