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

K平均法によるクラスタリング

K平均法によるクラスタリングの可視化
参考文献:集合知プログラミング(http://www.oreilly.co.jp/books/9784873113647/)
Get Adobe Flash player
by termat 25 Feb 2010
/**
 * Copyright termat ( http://wonderfl.net/user/termat )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/uKm0
 */

/*
	K平均法によるクラスタリングの可視化
	参考文献:集合知プログラミング(http://www.oreilly.co.jp/books/9784873113647/)
*/

package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.TextField;
	
	[SWF(framerate = "10", width = "500",height="500",backgroundColor="0x000000")]
	public class Practice31 extends Sprite{
		private var cont:Controller;
		private const numOfSample:int = 160;
		private const numOfGroup:int = 10;
		
		public function Practice31() {
			cont = new Controller(this, numOfGroup);	
			for (var i:int = 0; i < numOfSample; i++) {
				var m:Sample = new Sample();
				m.x = 500 * Math.random();
				m.y = 500 * Math.random();
				addChild(m);
				cont.sample.push(m);
			}
			addEventListener(Event.ENTER_FRAME,update);
		}
		
		private function update(e:Event):void {
			if (!cont.completed) {
				cont.update(e);
			}
		}
	}
}
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import caurina.transitions.Tweener;
class Controller {
	private var kave:Vector.<Cog>;
	public var sample:Vector.<Sample>;
	private var splite:Sprite;
	private var index:int;
	private var num:int;
	public var completed:Boolean = false;
	
	public function Controller(s:Sprite, n:int):void {
		splite = s;
		kave = new Vector.<Cog>();
		sample = new Vector.<Sample>();
		for (var i:int = 0; i < n; i++) {
			var cr:Number = (i / n) * 360.0;
			var k:Cog = new Cog(getColor(cr));
			k.x = 500 * Math.random();
			k.y = 500 * Math.random();
			kave.push(k);
			splite.addChild(k);
		}
		index = 0;
		num = 0;
	}
	
	public function update(e:Event):void {
		if (index < sample.length) {
			num +=checkGroup(index++);
		}else {
			splite.graphics.clear();
			if (num == 0) completed = true;
			if (completed)return;
			for (var i:int = 0; i < kave.length; i++) {
				var p:Point = kave[i].getGrav();
				Tweener.addTween( kave[i], { x:p.x, y:p.y, time:30, useFrames:true, transition:"easeOutExpo"});
				kave[i].clear();
			}
			index = 0;
			num = 0;
		}
	}
	
	private function checkGroup(i:int):int {
		splite.graphics.clear();
		var ret:int = sample[i].findGroup(kave);
		splite.graphics.lineStyle(1.0, 0xffff00);
		splite.graphics.moveTo(sample[i].group.x, sample[i].group.y);
		splite.graphics.lineTo(sample[i].x, sample[i].y);
		return ret;
	}
	
	private function getColor(i:int):uint {
		var h:Number = i / 60;
		var ii:Number = Math.floor(h);
		var ff:Number = h - ii;
		var p1:Number = 0.0;
		var p2:Number = 1.0 - ff;
		var p3:Number = 1.0 - (1.0 - ff);
		var rv:Number;
		var gv:Number;
		var bv:Number;
		switch(ii) {
			case 0:
				rv = 1.0;	gv = p3;	bv = p1;
				break;
			case 1:
				rv = p2;	gv = 1.0;	bv = p1;
				break;
			case 2:
				rv = p1;	gv = 1.0;	bv = p3;
				break;
			case 3:
				rv = p1;	gv = p2;	bv = 1.0;
				break;
			case 4:
				rv = p3;	gv = p1;	bv = 1.0;
				break;
			default:
				rv = 1.0;	gv = p1;	bv = p2;
		}
		var rr:int = Math.max(0, Math.min(255, rv * 255));
		var gg:int = Math.max(0, Math.min(255, gv * 255));
		var bb:int = Math.max(0, Math.min(255, bv * 255));
		var color:uint = (rr << 16) + (gg << 8) + bb;
		return color;
	}
}

class Cog extends MovieClip{
	private var list:Vector.<Sample>;
	public var color:uint = 0x666666;
	
	public function Cog(c:uint):void {
		list = new Vector.<Sample>();
		color = c;
		graphics.beginFill(color);
		graphics.drawCircle(0,0,12);
		graphics.endFill();
	}
	
	public function addSample(m:Sample):void {
		list.push(m);
	}
	
	public function removeSample(m:Sample):void {
		for (var i:int = 0; i < list.length; i++) {
			var obj:Sample = list.shift();
			if (m == obj) return;
			list.push(obj);
		}
	}
	
	public function clear():void {
		while (list.length > 0) list.pop();
	}
	
	public function distance(s:Sample):Number {
		var xx:Number = x - s.x;
		var yy:Number = y - s.y;
		return Math.sqrt(xx * xx + yy * yy);
	}

	public function getGrav():Point {
		if (list.length == 0) {
			return new Point(x, y);
		}else {
			var avex:Number = 0;
			var avey:Number = 0;
			for each(var m:Sample in list) {
				avex += m.x;
				avey += m.y;
			}
			return new Point(avex / list.length, avey / list.length);
		}
	}
}

class Sample extends MovieClip {
	public var group:Cog = null;
	private var size:Number = 20 * Math.random();
	
	public function Sample():void {
		draw(0xffffff);
	}
	
	public function findGroup(list:Vector.<Cog>):int {
		var tmp:Cog = null;
		var len:Number = 99999999;
		for each(var k:Cog in list) {
			var l:Number = k.distance(this);
			if (len > l) {
				tmp = k;
				len = l;
			}
		}
		if (group == tmp) {
			group.addSample(this);
			return 0;
		}else {
			if (group != null) group.removeSample(this);
			group = tmp;
			group.addSample(this);
			draw(group.color);
			return 1;
		}
	}
	
	private function draw(c:uint):void {
		graphics.clear();
		graphics.beginFill(c,0.4);
		graphics.drawCircle(0,0,size);
		graphics.endFill();
	}
}