blog.Ring.idv.tw

ActionScript 3.0

K-means algorithm in AS3

相較於前一篇所實作的KNN「分類」演算法,本篇所要實作的則是K-means「分群」演算法(Unsupervised learning),兩者同樣都是使用Euclidean distance來決定和中心點的距離計算,只不過K-means還需要反覆不斷的修正K個中心點,直到K個點慢慢地趨於穩定才算完成,詳細的程式如下:

(本範例K值為3,所以一開始在畫面上點擊滑鼠左鍵會先依序分配3個分群的中心點,接著再不斷地點擊滑鼠左鍵就可以觀察到K點的變化,玩玩看吧>>kmeans)

Kmeans.as

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.utils.*;
	
	public class Kmeans extends MovieClip
	{
		private var k:uint = 3;
		private var count:uint = 0;
		private var _r:uint = 0;
		private var _g:uint = 0;
		private var _b:uint = 0;
		private var k_center:Array = new Array();
		private var k_means:Array = new Array();
	
		public function Kmeans()
		{
			stage.addEventListener(MouseEvent.MOUSE_UP,put);
			init();
		}
		public function put(m:MouseEvent):void
		{
			if(count < k)
			{
				k_means[count] = new Array(); 
				var c:Circle = null;
				if(count == 0)
				{
					c = new Circle(0x0000FF);
				}else if(count == 1)
				{
					c = new Circle(0x00FF00);
				}else{
					c = new Circle(0xFF0000);
				}
				c.x = stage.mouseX;
				c.y = stage.mouseY;
				addChild(c);
				k_center[count] = c;
				count++;
				return;
			}
			for(var w = 0 ; w < 20 ; w++)
			{
				var cc2:Circle = this.getChildAt(w) as Circle;
				var k_arr:Array = new Array();
				var k_dict:Dictionary = new Dictionary(true);
				for(var v = 0 ; v < k ;v++)
				{
					var k_c = k_center[v];
					var dist2 = Point.distance(new Point(k_c.x,k_c.y),new Point(cc2.x,cc2.y));
					k_dict[dist2] = k_c;
					k_arr.push(dist2);
				}
				k_arr.sort(Array.NUMERIC);
				var min = k_arr[0];
				var color:uint = k_dict[min].getColor();
				cc2.reDraw(color);
				if(color == 0x0000FF)
				{
					k_means[0][_b] = new Point(cc2.x,cc2.y);
					_b++;
				}else if(color == 0x00FF00)
				{
					k_means[1][_g] = new Point(cc2.x,cc2.y);
					_g++;
				}else{
					k_means[2][_r] = new Point(cc2.x,cc2.y);
					_r++;
				}
			}
			trace(_r+" "+_g+" "+_b);
			var xx=0,yy=0;
			for(var bb = 0 ; bb < _b ; bb++)
			{
				xx += k_means[0][bb].x;
				yy += k_means[0][bb].y;
			}
			k_center[0].x = xx/_b;
			k_center[0].y = yy/_b;
			xx=0;yy=0;
			for(var gg = 0 ; gg < _g ; gg++)
			{
				xx += k_means[1][gg].x;
				yy += k_means[1][gg].y;
			}
			k_center[1].x = xx/_g;
			k_center[1].y = yy/_g;
			xx=0;yy=0;
			for(var rr = 0 ; rr < _r ; rr++)
			{
				xx += k_means[2][rr].x;
				yy += k_means[2][rr].y;
			}
			k_center[2].x = xx/_r;
			k_center[2].y = yy/_r;
			trace(k_center[0].x+" "+k_center[0].y);
		}
		public function init():void
		{
			for(var i = 0 ; i < 10 ; i++)
			{
				var c:Circle = new Circle(0x777777);				
				c.x = Math.random()*500;
				c.y = Math.random()*500;
				addChild(c);				
			}
			for(i = 0 ; i < 10 ; i++)
			{
				var c2:Circle = new Circle(0x777777);				
				c2.x = Math.random()*500;
				c2.y = Math.random()*500;
				addChild(c2);
			}
		}
	}
}

Circle.as

package
{
	import flash.display.*;
	
	public class Circle extends Sprite
	{
		private var color:uint = 0;
		
		public function Circle(c:uint)
		{
			this.color = c;
			this.graphics.lineStyle(5);
			this.graphics.beginFill(this.color);
			this.graphics.drawCircle(0,0,20);
			this.graphics.endFill();
		}
		public function getColor():uint
		{
			return this.color;
		}
		public function reDraw(color:uint):void
		{
			this.graphics.clear();
			this.graphics.lineStyle(5);
			this.graphics.beginFill(color);
			this.graphics.drawCircle(0,0,20);
			this.graphics.endFill();
			this.alpha = .5;
		}
	}
}

2010-04-27 23:34:38 | Comments (3)

KNN(K-nearest neighbor) algorithm in AS3

最近本來想打算藉由Flash CS5的發佈來開發iPhone應用程式,無奈Apple的大刀一揮~ 導致就算用Flash CS5開發出來的iPhone程式也通過不了上架的審核... 一下子打亂了我的一些計劃... 不過還是要練習練習AS3,而本文主要就是用AS3來實現KNN的基本概念,簡單來說KNN是一種可以藉由訓練資料來推測可能結果的演算法(Supervised learning),詳細的程式細節如下:

(本範例初始化的K值為5,玩玩看吧>>knn.swf)

KNN.as

package
{
	import flash.display.*;
	import flash.events.*;
	import flash.geom.Point;
	import flash.utils.*;
	
	public class KNN extends MovieClip
	{
		private var k:uint = 5;
	
		public function KNN()
		{
			stage.addEventListener(MouseEvent.MOUSE_UP,put);
			init();
		}
		public function put(m:MouseEvent):void
		{
			var c:Circle = null;			
			var num:uint = this.numChildren;
			trace(num);
			var k_dict:Dictionary = new Dictionary(true);
			var k_arr:Array = new Array();
			for(var i = 0 ; i < num ; i++)
			{
				var cc:Circle = this.getChildAt(i) as Circle;
				var dist = Point.distance(new Point(stage.mouseX,stage.mouseY),new Point(cc.x,cc.y));
				k_dict[dist] = i;
				k_arr.push(dist);
			}
			k_arr.sort(Array.NUMERIC);
			var blue = 0;
			var red = 0;
			for(var j = 0 ; j < k ; j++)
			{
				var nid = k_dict[k_arr[j]];
				var c2:Circle = this.getChildAt(nid) as Circle;
				var cor:uint = c2.getColor();
				trace(nid+" "+k_arr[j]+" "+cor);
				if(cor == 0x0000FF)
					blue++;
				else
					red++;
			}
			if(blue > red)
				c = new Circle(0x0000FF);				
			else
				c = new Circle(0xFF0000);				
			
			c.x = stage.mouseX;
			c.y = stage.mouseY;
			addChild(c);
		}
		public function init():void
		{
			for(var i = 0 ; i < 10 ; i++)
			{
				var c:Circle = new Circle(0xff0000);				
				c.x = Math.random()*500;
				c.y = Math.random()*500;
				addChild(c);				
			}
			for(i = 0 ; i < 10 ; i++)
			{
				var c2:Circle = new Circle(0x0000FF);				
				c2.x = Math.random()*500;
				c2.y = Math.random()*500;
				addChild(c2);
			}
		}
	}
}

Circle.as

package
{
	import flash.display.*;
	
	public class Circle extends Sprite
	{
		private var color:uint = 0;
		
		public function Circle(c:uint)
		{
			this.color = c;
			this.graphics.lineStyle(5);
			this.graphics.beginFill(this.color);
			this.graphics.drawCircle(0,0,20);
			this.graphics.endFill();
		}
		public function getColor():uint
		{
			return this.color;
		}
	}
}

相關資源

KNN演算法

KNN演算法 (更正篇)

2010-04-19 23:14:37 | Comments (2)

AS3 - Timeline_N

在上一篇「AS3在Document Class和Timeline」曾探討過將AS3程式寫在時間軸的時候,Flash編譯器會自動產生了一個Dynamic Class「MainTimeline」,那如果在Flash IDE建一個「MovieClip」,並在該元件的某個影格內加上「stop()」程式,而經由Flash CS4編譯器處理後會如何呢?

Decompiling:

package test_fla
{
    import flash.display.*;

    dynamic public class Timeline_1 extends MovieClip
    {
        public function Timeline_1()
        {
            addFrameScript(61, this.frame62);
            return;
        }
        function frame62()
        {
            stop();
            return;
        }
    }
}

如同上述的程式碼,在主時間軸的影格寫下AS3程式的話,Flash會產生「MainTimeline」Dynamic Class,若是在任一「MovieClip」內寫AS3程式,則會產生「Timeline_N」的Dynamic Class,而「N」整數就取決於Flash編譯器所決定的,不過我們也可以透過「getQualifiedClassName(this);」來取得該元件的類別名稱(如:Timeline_1),如此,既然知道該元件對應的類別是否就能如法泡製的複製一份呢?答案是肯定的,如下:

var rect:MovieClip = new Timeline_1();
rect.x = 100;
addChild(rect);

另外值得注意的是,就算只是寫下註解的字元「//」也會產生如下的程式碼:

package test_fla
{
    import flash.display.*;

    dynamic public class Timeline_1 extends MovieClip
    {

        public function Timeline_1()
        {
            addFrameScript(61, this.frame62);
            return;
        }
        function frame62()
        {
            return;
        }
    }
}

所以可見Flash編譯器在這部份未來仍然有值得改善的空間!

2009-12-10 23:25:15 | Comments (1)

AS3在Document Class和Timeline

在Flash IDE的開發環境下,我們不僅可以透過Document Class的方式來寫AS3程式,另外也可以透過時間軸(Timeline)的方式來達成,甚至還可以混合這兩種方式,那究竟寫在Document ClassTimeline兩者的寫法有何差異,底下各別來探討:

Document Class - Hello

Hello.as

package
{
	import flash.display.*;
	
	public class Hello extends MovieClip
	{
		public function Hello()
		{
			trace("Hello");
		}
	}
}

直接在Document Class中設為「Hello」並輸出swf檔案。

Decompiling:

package 
{
    import flash.display.*;

    public class Hello extends MovieClip
    {
        public function Hello()
        {
            trace("Hello");
            return;
        }
    }
}

從結果上來看,程式的結構上並沒有太大的變化,接下來看時間軸的作法。

Timeline - Hello

直接在時間軸Frame[0]寫下:

trace("Hello");

並直接發佈成swf檔案。

Decompiling:

package hello_fla
{
    import flash.display.*;

    dynamic public class MainTimeline extends MovieClip
    {
        public function MainTimeline()
        {
            addFrameScript(0, this.frame1);
            return;
        }
        function frame1()
        {
            trace("Hello");
            return;
        }
    }
}

經由時間軸的寫法可以發現,只有一行「trace("Hello");」程式完全被重新包裝,Flash編譯器自動產生了一個Dynamic Class「MainTimeline」來達成,而且原先的「trace("Hello");」程式並不是被寫在MainTimeline的Constructor之中,而是透過「addFrameScript」函式來明確地指定「Frame 0」位置來達成,那如果混合Document ClassTimeline的作法又是如何呢?

Document Class & Timeline - Hello

將上述「Hello.as」直接拿來使用,並在時間軸Frame[0]的位置加上「trace("Hello2");」來測試。

Decompiling:

package 
{
    import flash.display.*;

    public class Hello extends MovieClip
    {
        public function Hello()
        {
            addFrameScript(0, this.frame1);
            trace("Hello");
            return;
        }
        function frame1()
        {
            trace("Hello2");
            return;
        }
    }
}

透過Document ClassTimeline混合的作法可以發現,Flash編譯器會將Timeline上的程式加到Document ClassConstructor之中,所以如果從Runtime的「執行順序」上來看(非程式順序),該程式即會印出:

Hello
Hello2

2009-12-07 22:16:28 | Add Comment

Augmented Reality in Flash - FLARToolKit

Augmented Reality這個詞主要是在1990年的時候由波音公司的一位「Thomas Caudell」工程師所提出來的(根據wiki的說法),Augmented Reality可以讓我們將虛擬的產物和真實世界結合在一起,可以想像如1996年的一部「Space Jam」電影,該電影將虛擬世界的卡通人物和Michael Jordan結合的作法,只不過那是電影後製的處理手法,而Augmented Reality則是更能實際和生活中結合。

要建構這方面的應用最初可以透過Dr. Hirokazu Kato所開發的ARToolKit library,它是一個採用C/C++的函式庫,不過有許多熱心的人都已經將它移植到其它語言了,所以如果你是用Flash/ActionScript開發的話,那麼可以使用Saqoosha所移植的「FLARToolKit」,只是它也遵循著ARToolKit的腳步採用GNU General Public License,所以如果想商業化的話則必須取得它的Commercial License。

相關資源

手機科技可以讓你看到鬼了!

ARToolKit 實戰/教學(一) 建置篇

FlarToolkit/Flash Augmented Reality - Getting Started

Scorpio: FLARToolkit簡單教學

【教學】PV3D 結合 flartoolkit

2009-10-23 19:25:15 | Add Comment

Previous Posts
Copyright (C) Ching-Shen Chen. All rights reserved.

::: 搜尋 :::

::: 分類 :::

::: 最新文章 :::

::: 最新回應 :::

::: 訂閱 :::

Atom feed
Atom Comment