2009年8月27日 星期四

Artificial Neural Network--Random Learning Perceptron

最近開始研讀類神經網路的相關文章
打算開發類神經網路訓練來解讀股價走勢
以下程式碼改自別人的範例
是我的蹲馬步練基本功的初步成果
最基本的神經網路--感知器



import random, math
import string

from sympy import *

def hardlims(inputM,weightM,bias):
     n=(weightM*inputM)[0].evalf()-bias
     if n<0:
     a = -1
     if n>=0:
     a = 1
     return a

def sum_array(a):
     acc = 0
     for i in a:
     acc += i
     return acc

class NN:
def __init__(self):
     self.w1 = [random.random() for x in range(10)]
     self.w2 = [random.random() for x in range(10)]
     self.w3 = [random.random() for x in range(10)]
     self.bias = 0

def learn(self,input,target):
     errorAbsSum = 1
     epsilon = 1e-6

     iterations = 0
     while abs(errorAbsSum) > epsilon:
     iterations +=1
     errorAbsSum = 0
     counter = 0
     tmp1 = (sum_array(self.w1) / len(self.w1))
     tmp2 = (sum_array(self.w2) / len(self.w2))
     tmp3 = (sum_array(self.w3) / len(self.w3))
     for i,x in enumerate(input):
     activation = hardlims(Matrix(3,1,x),Matrix(1,3,[tmp1,tmp2,tmp3]),self.bias)
     error = target[i] - activation
     learningRate = random.random() / 10
     tmp1 += (error * learningRate * x[0])
     tmp2 += (error * learningRate * x[1])
     tmp3 += (error * learningRate * x[2])
     errorAbsSum += abs(error)
     print 'Learning:w1=%f w2=%f w3=%f learningRate=%f error=%f activation=%f' % ( tmp1, tmp2,tmp3,learningRate,error,activation)
     del self.w1[0], self.w2[0],self.w3[0]
     self.w1.append(tmp1)
     self.w2.append(tmp2)
     self.w3.append(tmp3)
     print 'Iterations: %d \n w1=%f w2=%f w3=%f' % (iterations, tmp1, tmp2,tmp3)


def test(self,x):
     tmp1 = (sum_array(self.w1) / len(self.w1))
     tmp2 = (sum_array(self.w2) / len(self.w2))
     tmp3 = (sum_array(self.w3) / len(self.w3))
     activation = hardlims(Matrix(3,1,x),Matrix(1,3,[tmp1,tmp2,tmp3]),self.bias)
     print 'test(%s):result=%d w1=%f w2=%f w3=%f' % (x, activation, tmp1, tmp2,tmp3)


if __name__ == '__main__':
     input =[[-1,-1,-1],[1,1,1],[1,-1,-1]]
     target = [-1,1,1]

     nn=NN();
     nn.learn(input,target)
     nn.test([1,1,1])
     nn.test([1,1,-1])
     nn.test([1,-1,1])
     nn.test([1,-1,-1])
     nn.test([-1,1,1])
     nn.test([-1,1,-1])
     nn.test([-1,-1,1])
     nn.test([-1,-1,-1])


驗收訓練成果

test([1, 1, 1]):result=1 w1=0.663924 w2=0.276574 w3=0.333518
test([1, 1, -1]):result=1 w1=0.663924 w2=0.276574 w3=0.333518
test([1, -1, 1]):result=1 w1=0.663924 w2=0.276574 w3=0.333518
test([1, -1, -1]):result=1 w1=0.663924 w2=0.276574 w3=0.333518
test([-1, 1, 1]):result=-1 w1=0.663924 w2=0.276574 w3=0.333518
test([-1, 1, -1]):result=-1 w1=0.663924 w2=0.276574 w3=0.333518
test([-1, -1, 1]):result=-1 w1=0.663924 w2=0.276574 w3=0.333518
test([-1, -1, -1]):result=-1 w1=0.663924 w2=0.276574 w3=0.333518


縮排有點亂
有誰能指點一下?

2009年8月18日 星期二

FP10 Native 3D Diffuse Shading demo(STOK3D Filters)

我的Banner目前以FP10 Native 3D改寫
而濾鏡則用stok3d所提供的以Pixel Bender開發的各式濾鏡
改天試試看PV3D+Pixel Bender
不過自從Flash Player 10加上Native 3D特性後
用不用PV3D倒不是那麼重要了
不過還是很感謝PV3D相關開發人員的無私奉獻!!!

2009年8月5日 星期三

GAE--使用Memcache Python API

隨著股票看盤程式固定時間間隔要抓取的資料變多
資料回應的時間也越來越慢了,甚至每次程式啟動時都需要等上10幾秒
該是加入Memcache(快取)的時候了
很簡單,只要加入下列幾行code即可
from google.appengine.api import memcache

class getQuote(webapp.RequestHandler):
    def get(self):
       data = memcache.get(stkno_string)
       if data is None:
           data = self.query_for_data()
           #快取將資料保留20秒
           memcache.add(stkno_string, data, 20)
       self.response.out.write(data)

2009年8月2日 星期日

GAE--在 Python 使用 Cron 排程工作

在寫股價看盤軟體時需要上一個營業日的收盤價才能計算漲跌幅
所以必須在開盤前更新最新的收盤價才能算出正確的漲跌幅
這時Google App Engine提供的Cron Service就派上用場了,可以定期設定排程工作,
Cron會在每天的指定時間啟動網址,但還是與一般 HTTP request一樣有時間的限制。

一開始很高興的寫一大堆code撈DataStore的資料,
但是經過幾次request timeout後,只好乖乖的將一些繁雜的工作,
切成好幾分轉給其他的URL負責,讓cron啟動的URL只負責簡單的資料清空的動作
整個程式就可以正常運行了

下列是 cron.yaml 檔案的範例:

cron:
- description: daily update job
url: /tasks/updatedata
schedule: every 24 hours

2009年7月24日 星期五

3D股價看盤軟體



最近台股上攻七千點
開發一個自用股價看盤小工具
目前只有"低調看盤模式"^ ^
單獨開個網頁視窗縮小後擺在桌面角落
即可低調看盤
3D的功能還沒完全放上去所以沒開放,哈哈

目前的功能有
1.隱藏文字功能--當滑鼠離開時會隱藏文字
2.自選股記憶功能--當程式重啟時,不需再次輸入自選股代號


[demo]

2009年7月7日 星期二

PV3D--Box2DFlash Jigsaw Puzzle


這個拼圖積木是參考以下兩個網站改寫的
http://www.lamberta.org/blog/paperbox2d/
http://pv3d.org/tag/box2dflash/
比較麻煩的是如何將小方塊組成有凹凸狀的積木,而且小方塊一多效率就變慢了
[demo]

2009年7月2日 星期四

如何讓Flex's swf減肥

當FLEX專案最後產出 swf 的時候,可以在
「功能表選單 => Project => Properties => Flex Compiler 」將「 -locale en_US 」改成「-locale en_US -debug=false 」
可讓每個 swf 減少100KB。但是這樣做會把除錯訊息整個隱藏。

如果是Actionscript專案,好像也能減肥大約10KB左右,不無小補^ ^

2009年6月25日 星期四

PV3d--jiglibflash Jigsaw Puzzle拼圖積木

雖然新版本的jiglibflash套用了 "門面樣式"Facade pattern隱藏許多實作的細節讓寫code時少了好幾行,
不過拉皮整形後的jiglibflash目前似乎還只能拿來當玩具玩玩,物體還是不小心就穿牆而過,
提供的幾個Constraint類別鬆垮垮的好像快斷的橡皮筋,
不過如果未來能做到DAE類別的碰撞偵測,jiglibflash還是大有可為的

以下是拼圖積木測試
[demo]

2009年6月17日 星期三

有關Google App Engine的Datastore

最近在研究GAE Datastore
發覺這真是搞OO的夢幻逸品啊!!!
想當年被EJB、DataModel、OR MAPING等等搞得焦頭爛額時
掙扎於理想(OO)與現實(DB)之間
為了能讓整個專案能順利進行
也曾將資料實體(Entity)塞到類似Dictionary的資料結構中
再序列化(Serialize)存至檔案
網頁及相關商業邏輯都可以即時demo給客戶看
不過以往大型專案沒有擺個Oracle或Informix的大型資料庫是無法讓主管及業主信任的
光是出報表套印就無法過關
還好有雲端運算的支持
類似GAE Datastore的理念應該會越普及吧!!!

備忘一下,維護本地端datastore可到
http://localhost:8080/_ah/admin/datastore

2009年6月13日 星期六

PV3D-- Guestbook( 訪客登記簿)

很久以前就想用PV3D寫個留言板
但是因為對後端Google App Engine的Python不熟
所以僅止於想想而已
一直沒有付諸行動
直到最近看了pyAMF一些範例
覺得Flash+Python似乎沒想像中那麼難
於是動手寫了左邊的訪客登記簿
目前只完成到預期功能的10%

翻頁的效果目前不是很優
有空再改改....

ps.原本用as3寫大小只有200K,改成mxml後暴增為500K,要如何減肥啊?

2009年6月3日 星期三

Papervision3D-Lens Flare


很久之前就知道PV3D的LensFlare特效但一直找不到時間測試
上網找到最早的一篇範例在http://blog.zupko.info/
但上面提供的原始碼有點老舊
好不容易找到這篇Papervision 2 Great White Lens Flares
根據此文作者提供的程式段落做一番修改後
再使用GIMP做幾個鏡頭眩光圖
這樣子PV3D的LensFlare特效就可以順利跑起來了

private function init():void {


light = new PointLight3D(true);
light.x = 0;
light.z = 100;
light.y = 400;

light.autoCalcScreenCoords=true;

view.scene.addChild(light);


//create some halos
var h:Bitmap = new Halo();
var h1:Bitmap = new Halo1();
var h2:Bitmap = new Halo2();

var flareArray:Array = [h,h2,h1 ];
lensFlare = new LensFlare(light, flareArray,300,300);


var lightLayer : ViewportLayer = view.viewport.getChildLayer(light);
lightLayer.addLayer(lensFlare);
lightLayer.layerIndex = 1;

addEventListener( Event.ENTER_FRAME, enterFrameHandler );

}

private function enterFrameHandler( event : Event ):void {


lensFlare.updateFlare(true);
view.singleRender();
}

[demo]

2009年5月20日 星期三

PV3D-中文VECTORVISION範例


這個程式改自PV3D-VECTORVISION套件自帶範例
中文Font3D字型類別則以自己改寫的AIR程式轉出
百多個中文字須轉很久不是很有效率
還在改寫中

swf檔案大小:260K
ps.銀幕解析度須調到1024*768以上才能看到右邊的控制項
[demo]

2009年5月10日 星期日

PV3D --Man In Hat + Font3D


花了一些時間用Blender做了個黑帽人
配上簡單的骨骼系統
PV3D顯示中文字也不再需要搭配耗記憶體的字型檔
整個SWF共179K


[demo]

2009年4月29日 星期三

簡單的FK(Forward Kinematics)Algorithm

這是從討論以FK轉換化學鍵方位的文章看來的公式
[X',Y',Z',1]t=Mrt(i,theta)[X,Y,Z,1]t

[X',Y',Z',1]t為轉換後的頂點
Mrt為旋轉平移矩陣
[X,Y,Z,1]t為轉換後的頂點
i代表各根骨頭
theta為各Bone Joint的旋轉角度

PV3D Bone FK(Forward Kinematics)試作--回眸轉臂

經過好幾天眼睛幾乎快脫窗的測試
終於確認原本的四元數(Quaternion)旋轉矩陣運算程式碼無誤
需要在Blender建模階段將骨頭(Bone)與頂點(Vertex)對應關係處理好
正向運動(Forward Kinematics)才能順利運轉

當初搞不定PV3D的DAE類別
一來可能就是產生的檔案太大(50frames動輒超出1M)
二來就是建模階段的對應關係沒處理好(有時會出現骨頭位置喬好後,切換到編輯模式竟然會跑出Mesh的範圍)
所以才無法正常運作

目前關節部位(Joints)的旋轉還要加上權重值的運算才不會產生扭曲
以下是展示程式


頂點:1146
面數:2268
SWF檔案:169K
[Demo]

2009年4月22日 星期三

PV3D Bone FK(Forward Kinematics)試作-美女變怪獸

最近嘗試實作FK(Forward Kinematics)
本來的想法是讓美女彎個腰
移動Spine牽動Neck再牽動Head
可惜在Blender建立骨頭與頂點對應關係時沒處理好
美女就變成怪獸了

頂點:762
面數:1500
SWF檔案:157K
[Demo]

2009年4月2日 星期四

PV3D Bone Rotation and Quaternion

PV3D的DAE類別測試了許久
總是會遇到一些大大小小的障礙
搜遍了NABBLE的討論文章
也找不到適合我的解決之道
無奈只好捲起袖子試著"重新發明輪子"
K了一些硬梆梆的有關數學及三D理論的網路文章
硬著頭皮寫下這個很粗糙的程式碼
主要是將人物四肢所屬的頂點索引塞到不同的Group
再分別以不同的四元數(Quaternion)旋轉之
當然還有很多細節還沒處理好
不過時間有限
先這樣子留個紀錄......


[demo]


package {
import flash.utils.Dictionary;

import org.papervision3d.core.geom.TriangleMesh3D;
import org.papervision3d.core.geom.renderables.Triangle3D;
import org.papervision3d.core.geom.renderables.Vertex3D;
import org.papervision3d.core.math.*;
import org.papervision3d.core.proto.MaterialObject3D;

public class CubeMan extends TriangleMesh3D {
private var ve:Array;
private var fa:Array;
private var vertGroupDict:Dictionary = new Dictionary();

public function aaa(material : MaterialObject3D ) {
super( material, new Array(), new Array() );
ve = this.geometry.vertices;
fa = this.geometry.faces;
v(1.000000,-1.000000,1.000000);
v(1.000000,-1.000000,-1.000000);
v(-1.000000,-1.000000,-1.000000);
v(-1.000000,-1.000000,1.000000);
v(1.000000,1.000000,0.999999);
v(0.999999,1.000000,-1.000001);
v(-1.000000,1.000000,-1.000000);
v(-1.000000,1.000000,1.000000);
v(-1.000000,-1.000000,-2.806856);
v(-1.000000,1.000000,-2.806855);
v(1.000000,-1.000000,-2.806856);
v(0.999999,1.000000,-2.806856);
v(1.000000,-1.000000,-4.640568);
v(-1.000001,-1.000000,-4.640568);
v(-1.000001,1.000000,-4.640568);
v(0.999999,1.000000,-4.640569);
v(-1.000001,-1.000000,-6.226972);
v(-1.000001,1.000000,-6.226972);
v(0.999999,-1.000000,-6.226972);
v(0.999999,1.000000,-6.226973);
v(2.975521,-1.000000,-4.640568);
v(2.975521,-1.000000,-6.226972);
v(2.975520,1.000000,-6.226973);
v(2.975521,1.000000,-4.640569);
v(-3.035387,1.000000,-4.640568);
v(-3.035387,1.000000,-6.226972);
v(-3.035387,-1.000000,-6.226972);
v(-3.035387,-1.000000,-4.640568);
v(0.999999,0.999999,-9.615506);
v(2.975520,1.000000,-9.615506);
v(2.975521,-1.000000,-9.615505);
v(0.999999,-1.000001,-9.615505);
v(0.999999,0.999996,-15.988734);
v(0.999999,-1.000004,-15.988733);
v(2.975521,-1.000003,-15.988733);
v(2.975520,0.999996,-15.988734);
v(-1.000001,-0.999999,-9.610606);
v(-3.035387,-1.000000,-9.610606);
v(-3.035387,1.000000,-9.610606);
v(-1.000001,1.000001,-9.610606);
v(-1.000001,-0.999999,-15.983833);
v(-1.000001,1.000001,-15.983833);
v(-3.035387,1.000000,-15.983833);
v(-3.035387,-1.000000,-15.983833);
v(-0.999999,-1.000000,2.229123);
v(-1.000000,1.000000,2.229123);
v(1.000000,-1.000000,2.229122);
v(1.000001,1.000000,2.229122);
v(-0.999999,-1.000000,2.229123);
v(1.000000,-1.000000,2.229122);
v(-1.000000,1.000000,2.229123);
v(1.000001,1.000000,2.229122);
v(-0.999999,-0.999999,4.732891);
v(-0.999999,1.000001,4.732890);
v(1.000001,-0.999999,4.732890);
v(1.000001,1.000001,4.732890);
v(1.000000,-1.000000,1.000000);
v(1.000000,1.000000,0.999999);
v(1.000000,-1.000000,-1.000000);
v(0.999999,1.000000,-1.000001);
v(3.994711,-1.000000,0.999999);
v(3.994711,-1.000000,-1.000001);
v(3.994712,1.000000,0.999998);
v(3.994711,1.000000,-1.000002);
v(8.607256,-1.000000,0.999996);
v(8.607256,1.000000,0.999996);
v(8.607256,-1.000000,-1.000004);
v(8.607255,1.000000,-1.000004);
v(8.607256,-1.000000,-1.000004);
v(8.607256,-1.000000,0.999996);
v(8.607255,1.000000,-1.000004);
v(8.607256,1.000000,0.999996);
v(12.600204,1.000001,0.999994);
v(12.600204,-0.999999,0.999994);
v(12.600203,1.000001,-1.000006);
v(12.600204,-0.999999,-1.000005);
v(-4.202740,-1.000000,1.000000);
v(-4.202740,1.000000,1.000000);
v(-4.202740,-1.000000,-1.000000);
v(-4.202740,1.000000,-1.000000);
v(-8.722494,-1.000000,-0.999998);
v(-8.722494,-1.000000,1.000003);
v(-8.722494,1.000000,-0.999997);
v(-8.722494,1.000000,1.000002);
v(-12.583741,1.000000,1.000002);
v(-12.583741,-1.000000,1.000003);
v(-12.583741,1.000000,-0.999997);
v(-12.583741,-1.000000,-0.999998);

f(87,86,84);
f(87,84,85);
f(81,80,87);
f(81,87,85);
f(82,83,84);
f(82,84,86);
f(80,82,86);
f(80,86,87);
f(83,81,85);
f(83,85,84);
f(77,76,81);
f(77,81,83);
f(78,79,82);
f(78,82,80);
f(79,77,82);
f(77,83,82);
f(76,78,80);
f(76,80,81);
f(3,2,76);
f(2,78,76);
f(6,7,77);
f(6,77,79);
f(2,6,79);
f(2,79,78);
f(7,3,77);
f(3,76,77);
f(73,72,75);
f(72,74,75);
f(68,69,73);
f(68,73,75);
f(71,70,74);
f(71,74,72);
f(70,68,74);
f(68,75,74);
f(69,71,73);
f(71,72,73);
f(64,65,71);
f(64,71,69);
f(67,66,68);
f(67,68,70);
f(65,67,70);
f(65,70,71);
f(66,64,69);
f(66,69,68);
f(61,60,64);
f(61,64,66);
f(62,63,67);
f(62,67,65);
f(63,61,67);
f(61,66,67);
f(60,62,64);
f(62,65,64);
f(56,57,60);
f(57,62,60);
f(59,58,63);
f(58,61,63);
f(57,59,63);
f(57,63,62);
f(58,56,60);
f(58,60,61);
f(1,0,56);
f(1,56,58);
f(4,5,59);
f(4,59,57);
f(5,1,58);
f(5,58,59);
f(0,4,57);
f(0,57,56);
f(55,54,53);
f(54,52,53);
f(49,48,52);
f(49,52,54);
f(50,51,55);
f(50,55,53);
f(51,49,55);
f(49,54,55);
f(48,50,53);
f(48,53,52);
f(44,45,50);
f(44,50,48);
f(47,46,49);
f(47,49,51);
f(45,47,51);
f(45,51,50);
f(46,44,48);
f(46,48,49);
f(0,3,44);
f(0,44,46);
f(7,4,47);
f(7,47,45);
f(4,0,46);
f(4,46,47);
f(3,7,45);
f(3,45,44);
f(40,41,42);
f(40,42,43);
f(37,36,40);
f(37,40,43);
f(38,37,43);
f(38,43,42);
f(39,38,42);
f(39,42,41);
f(36,39,41);
f(36,41,40);
f(16,17,36);
f(17,39,36);
f(17,25,38);
f(17,38,39);
f(25,26,37);
f(25,37,38);
f(26,16,36);
f(26,36,37);
f(32,33,35);
f(33,34,35);
f(29,28,32);
f(29,32,35);
f(30,29,35);
f(30,35,34);
f(31,30,34);
f(31,34,33);
f(28,31,33);
f(28,33,32);
f(19,18,31);
f(19,31,28);
f(18,21,30);
f(18,30,31);
f(21,22,30);
f(22,29,30);
f(22,19,28);
f(22,28,29);
f(24,27,25);
f(27,26,25);
f(14,13,27);
f(14,27,24);
f(13,16,27);
f(16,26,27);
f(17,14,24);
f(17,24,25);
f(20,23,21);
f(23,22,21);
f(12,15,23);
f(12,23,20);
f(15,19,22);
f(15,22,23);
f(18,12,21);
f(12,20,21);
f(18,19,16);
f(19,17,16);
f(13,12,18);
f(13,18,16);
f(15,14,17);
f(15,17,19);
f(9,8,14);
f(8,13,14);
f(10,11,12);
f(11,15,12);
f(11,9,14);
f(11,14,15);
f(8,10,12);
f(8,12,13);
f(2,1,8);
f(1,10,8);
f(5,6,9);
f(5,9,11);
f(1,5,10);
f(5,11,10);
f(6,2,9);
f(2,8,9);
f(4,7,5);
f(7,6,5);
f(0,1,2);
f(0,2,3);


/*GroupName=LeftHand.002*/
vertGroupDict["LeftHand.002"]= new Array();
vertGroupDict["LeftHand.002"].push(76);
vertGroupDict["LeftHand.002"].push(77);
vertGroupDict["LeftHand.002"].push(79);
vertGroupDict["LeftHand.002"].push(80);
vertGroupDict["LeftHand.002"].push(81);
vertGroupDict["LeftHand.002"].push(82);
vertGroupDict["LeftHand.002"].push(83);
vertGroupDict["LeftHand.002"].push(84);
vertGroupDict["LeftHand.002"].push(85);
vertGroupDict["LeftHand.002"].push(86);
vertGroupDict["LeftHand.002"].push(87);

/*GroupName=RightHand.002*/
vertGroupDict["RightHand.002"]= new Array();
vertGroupDict["RightHand.002"].push(62);
vertGroupDict["RightHand.002"].push(63);
vertGroupDict["RightHand.002"].push(64);
vertGroupDict["RightHand.002"].push(65);
vertGroupDict["RightHand.002"].push(66);
vertGroupDict["RightHand.002"].push(67);
vertGroupDict["RightHand.002"].push(68);
vertGroupDict["RightHand.002"].push(69);
vertGroupDict["RightHand.002"].push(70);
vertGroupDict["RightHand.002"].push(71);
vertGroupDict["RightHand.002"].push(72);
vertGroupDict["RightHand.002"].push(73);
vertGroupDict["RightHand.002"].push(74);
vertGroupDict["RightHand.002"].push(75);



/*GroupName=LeftLeg.1*/
vertGroupDict["LeftLeg.1"]= new Array();
vertGroupDict["LeftLeg.1"].push(17);
vertGroupDict["LeftLeg.1"].push(25);
vertGroupDict["LeftLeg.1"].push(26);
vertGroupDict["LeftLeg.1"].push(36);
vertGroupDict["LeftLeg.1"].push(37);
vertGroupDict["LeftLeg.1"].push(38);
vertGroupDict["LeftLeg.1"].push(39);
vertGroupDict["LeftLeg.1"].push(40);
vertGroupDict["LeftLeg.1"].push(41);
vertGroupDict["LeftLeg.1"].push(42);
vertGroupDict["LeftLeg.1"].push(43);


/*GroupName=RightLeg.1*/
vertGroupDict["RightLeg.1"]= new Array();
vertGroupDict["RightLeg.1"].push(18);
vertGroupDict["RightLeg.1"].push(19);
vertGroupDict["RightLeg.1"].push(21);
vertGroupDict["RightLeg.1"].push(22);
vertGroupDict["RightLeg.1"].push(28);
vertGroupDict["RightLeg.1"].push(29);
vertGroupDict["RightLeg.1"].push(30);
vertGroupDict["RightLeg.1"].push(31);
vertGroupDict["RightLeg.1"].push(32);
vertGroupDict["RightLeg.1"].push(33);
vertGroupDict["RightLeg.1"].push(34);
vertGroupDict["RightLeg.1"].push(35);

this.x = 0.070997;
this.y = 0.051119;
this.z = 6.759333;

this.rotationX = 0.000000;
this.rotationY = 0.000000;
this.rotationZ = 0.000000;

this.scaleX = 1.000000;
this.scaleY = 1.000000;
this.scaleZ = 1.000000;

this.geometry.ready = true;

}
public function v(x:Number, y:Number, z:Number):void {
ve.push(new Vertex3D(x, y, z));
}


public function f(vertexIndex1:Number, vertexIndex2:Number, vertexIndex3:Number):void {
var face:Triangle3D = new Triangle3D(this, [ve[vertexIndex1], ve[vertexIndex2], ve[vertexIndex3]], null, []);
fa.push(face);
}

private var counter : int = 0;
private var theta:Number = (Math.PI/20);
public function apply():void {
var rQ : Quaternion;
var vs:Array = vertGroupDict["RightHand.002"];
var vc:int = vs.length;
var vsl:Array = vertGroupDict["LeftHand.002"];
var vcl:int = vsl.length;
var vsrr:Array = vertGroupDict["RightLeg.1"];
var vcrr:int = vsl.length;
var vsll:Array = vertGroupDict["LeftLeg.1"];
var vcll:int = vsl.length;

counter++;
if(counter==5)
{
counter = 0;
theta = -theta;
}
for (var i:int = 0; i < vc; i++) {
var v:Vertex3D = ve[vs[i]];
var n:Number3D = v.toNumber3D();
rQ = Quaternion.createFromAxisAngle(0,1,0,theta);
Matrix3D.multiplyVector4x4(rQ.matrix, n);
v.x = n.x;
v.y = n.y;
v.z = n.z;

}

for (var i:int = 0; i < vcl; i++) {
var v:Vertex3D = ve[vsl[i]];
var n:Number3D = v.toNumber3D();
rQ = Quaternion.createFromAxisAngle(0,1,0,-theta);
Matrix3D.multiplyVector4x4(rQ.matrix, n);
v.x = n.x;
v.y = n.y;
v.z = n.z;

}

for (var i:int = 0; i < vcrr; i++) {
var v:Vertex3D = ve[vsrr[i]];
var n:Number3D = v.toNumber3D();
rQ = Quaternion.createFromAxisAngle(1,0,0,theta);
Matrix3D.multiplyVector4x4(rQ.matrix, n);
v.x = n.x;
v.y = n.y;
v.z = n.z;

}


for (var i:int = 0; i < vcll; i++) {
var v:Vertex3D = ve[vsll[i]];
var n:Number3D = v.toNumber3D();
rQ = Quaternion.createFromAxisAngle(1,0,0,-theta);
Matrix3D.multiplyVector4x4(rQ.matrix, n);
v.x = n.x;
v.y = n.y;
v.z = n.z;

}


}

}
}

2009年3月7日 星期六

Font3D + as3dmod Bend中文字環測試



在Nabble討論區有人問到如何Bendding Text3D,解決的方法將每個Font3D字的頂點複製到Text3D的mesh裡頭,這樣一來as3dmod就能取mesh而彎之了

以下是Andy Zupko及Mark Barcinski-2兩位提出解法的程式碼片段


private function flattenText3D(t : Text3D) : void {
for each(var l:VectorLetter3D in t.letters) {
t.graphics.beginFill(l.material.fillColor);
t.graphicsCommands = t.graphicsCommands.concat(l.graphicsCommands);

for each( var v:Vertex3D in l.geometry.vertices){
var n:Number3D = v.toNumber3D();
Matrix3D.multiplyVector4x4(l.transform, n);
v.x = n.x;
v.y = n.y;
v.z = n.z;

t.geometry.vertices.push(v);
}

t.graphics.endFill();
t.removeChild(l);
}
}





至於為何我的demo可以做到字環
那就要從Bend類別說起
詳情待續......

[demo]

2009年2月23日 星期一

Delaunay Triangulation & DynamicFont3D中文字測試


這兩篇文章http://labs.zavoo.com/?p=141 http://labs.zavoo.com/?p=152提到如何將PV3D的Font3D延展成立體字型
以下是中文字型測試
字的底部有個類似底線延展成的平面
我還在找它出現的原由

ps.
經過測試後那個平面真的是底線造成的
當Font3D還沒沿Z軸延展時是看不出來的
只要去掉那幾個向量命令即可


[demo]

2009年2月19日 星期四

DynamicFont3D中文字測試


終於等到高手釋出DynamicFont3D(參看http://labs.zavoo.com/?p=105)
趕忙寫了個中文字測試
原程式碼會將整個GlyphTable載入記憶體
遇到中文字型檔的話肯定會塞到爆
所以只要動點手腳挑字
就能在PV3D秀中文啦!!!



[demo]

2009年2月4日 星期三

新推出的適用於PV3D物理系統Jiglibflash


JigLibFlash是一套新推出的適用於PV3D物理系統Jiglibflash,可偵測球體與方塊的碰撞,以下是我的範例


[Demo]

2009年1月14日 星期三

動態改變Collada物件的材質


這是動態改變Collada物件face材質的範例


for each(var face:Triangle3D in mesh.geometry.faces)
{
var color:Number = Math.random() * 0xffffff;
if(face.material.name == "Material_001")
{
face.material = new ColorMaterial(color);
}
............
}


[demo]

2009年1月8日 星期四

PV3D春聯(PV3D Spring Festival Couplets)

年關將近
打算用PV3D做些春聯當作練習
相關作品集中在這裡
http://3dspringfestivalcouplets.appspot.com