??xml version="1.0" encoding="utf-8" standalone="yes"?>亚洲国产成人精品91久久久
,色综合久久综合中文综合网,色综合久久88色综合天天 http://www.shnenglu.com/billhsu/category/7689.htmlzh-cn Tue, 01 Feb 2011 08:19:05 GMT Tue, 01 Feb 2011 08:19:05 GMT 60 Android游戏计时 http://www.shnenglu.com/billhsu/archive/2011/01/30/139627.htmlBill Hsu Bill Hsu Sun, 30 Jan 2011 15:16:00 GMT http://www.shnenglu.com/billhsu/archive/2011/01/30/139627.html http://www.shnenglu.com/billhsu/comments/139627.html http://www.shnenglu.com/billhsu/archive/2011/01/30/139627.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/139627.html http://www.shnenglu.com/billhsu/services/trackbacks/139627.html http://androgeek.info/?p=299 以前代码l验很多都是Zwindows的,所以对android下面的计时函C是太了解?br> 在写Friut3D Ӟ我用的代码是用gettimeofday()来计时的。但是效果不好,游戏里有个场景跑h十分卡,acepig兄和我都觉得q个问题很诡异。开始觉得这是模型的问题Q现在看来是计时函数不精惹得祸?br> 看看当时写的获取pȝ旉的代码:
static long getTime( void ) { gettimeofday( & now, NULL); return ( long )(now.tv_sec * 1000 + now.tv_usec / 1000 ); }
今天在一个google讨论l里得知gettimeofday()记得的tick是不准确的。而这个游戏逻辑依赖于time delta来计各个物体运动,计时不精,渲染自然会卡ѝ?br> 于是用纳U的准度的clock_gettime()重写了getTime()函数Q?br>
static long _getTime( void ) { struct timespec now; clock_gettime(CLOCK_MONOTONIC, & now); return now.tv_sec * 1000000 + now.tv_nsec / 1000 ; }
改了计时函数后,游戏各个场景都流畅了?br> ]]> Android NDK 开发OpenGL ES 2.0一些注意点 http://www.shnenglu.com/billhsu/archive/2010/08/10/122914.htmlBill Hsu Bill Hsu Tue, 10 Aug 2010 03:37:00 GMT http://www.shnenglu.com/billhsu/archive/2010/08/10/122914.html http://www.shnenglu.com/billhsu/comments/122914.html http://www.shnenglu.com/billhsu/archive/2010/08/10/122914.html#Feedback 1 http://www.shnenglu.com/billhsu/comments/commentRss/122914.html http://www.shnenglu.com/billhsu/services/trackbacks/122914.html 自己也试了试用NDK~一个OpenGL ES 2.0的程序,可是Q编译的时候出C一大堆错?br> 如图Q满屏幕都是 undefined reference to 那些OpenGL ES函数?br>看来是库文g没有链接q来?br> q是NDK例子里的Android.mk的写法:
LOCAL_PATH: = $(call my - dir) include $(CLEAR_VARS) LOCAL_MODULE : = libgl2jni LOCAL_CFLAGS : = - Werror LOCAL_SRC_FILES : = gl_code.cppLOCAL_LDLIBS : = -llog - lGLESv2 include $(BUILD_SHARED_LIBRARY)
问题出在用U色标出的那行?br> 把那句修改ؓQ?br>
LOCAL_LDLIBS : = - L$(SYSROOT) / usr / lib - llog LOCAL_LDLIBS +=- L$(SYSROOT) / usr / lib - lGLESv2
可以正常编译了?br> q有一些注意点是: ~译E序前要cleanQ否则编译会出错Q?br>每次更新了自q.so文g后,在eclipse的那个java目里要记着refresh一下?br> ]]> 靠得住的休眠函数XSleep http://www.shnenglu.com/billhsu/archive/2010/07/30/121679.htmlBill Hsu Bill Hsu Fri, 30 Jul 2010 02:55:00 GMT http://www.shnenglu.com/billhsu/archive/2010/07/30/121679.html http://www.shnenglu.com/billhsu/comments/121679.html http://www.shnenglu.com/billhsu/archive/2010/07/30/121679.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/121679.html http://www.shnenglu.com/billhsu/services/trackbacks/121679.html 今天在csdn上看C一文章:http://blog.csdn.net/lanzhengpeng2/archive/2008/05/06/2401554.aspx 讲的也正好是q个问题Q记录一下?br> 在用timeGetTime()的代码块的前后加?span class="Apple-style-span" style="border-collapse: separate; color: #000000; font-family: Simsun; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; font-size: medium;">timeBeginPeriod(1)?/span> timeEndPeriod(1)Q就可以提高 timeGetTime()的精度?br> 同时Q可以利用timeSetEvent写了一个靠得住的休眠函数[代码来自上述文章]Q?br>
static void XSleep(DWORD dwDelay,HANDLE hEvent) { MMRESULT hTimer = timeSetEvent(dwDelay, 1 ,(LPTIMECALLBACK)hEvent, 0 ,TIME_ONESHOT | TIME_CALLBACK_EVENT_SET); MsgWaitForMultipleObjectsEx( 1 , & hEvent,INFINITE,QS_ALLINPUT, 0 ); // 当有Windows消息Ӟq能l箋处理Windows消息。故选择了这个函数?/span> timeKillEvent(hTimer); }
消息循环[代码来自上述文章]Q?br>
MSG msg; DWORD dwLastTime; HANDLE hSleepEvent = CreateEvent(NULL,FALSE,FALSE,NULL); timeBeginPeriod( 1 ); dwLastTime = timeGetTime(); while (isActive()) { // 需要一直处理Windows消息到无消息处理为止 for (;PeekMessage( & msg,NULL, 0 , 0 ,PM_REMOVE);) { if (msg.message == WM_QUIT) { CloseHandle(hSleepEvent); timeEndPeriod( 1 ); return ; } if ( ! TranslateAccelerator(msg.hwnd,hAccelTable, & msg)) { TranslateMessage( & msg); DispatchMessage( & msg); } } DWORD FrameDelay = max( 1 , 1000 / max( 1 ,GetMaxFPS())); DWORD dwTime = timeGetTime(); if (dwLastTime + FrameDelay > dwTime) { XSleep(dwLastTime + FrameDelay - dwTime,hSleepEvent); } else { update(); dwLastTime += ((dwTime - dwLastTime) / FrameDelay) * FrameDelay; // 当实际C重低于预期数时Q这D代码可以完成蟩帧功能;当实际数大于等于预期数时Q这D代码仍然可以帧之间的旉间隔固定。之前谢Boss没有处理好的主要是q个?/span> } } CloseHandle(hSleepEvent); timeEndPeriod( 1 );
q样Q时间误差就会在1ms之内了,游戏也就不会抖动了?br> ]]> fstream那些?/title> http://www.shnenglu.com/billhsu/archive/2010/03/27/110683.htmlBill Hsu Bill Hsu Sat, 27 Mar 2010 10:37:00 GMT http://www.shnenglu.com/billhsu/archive/2010/03/27/110683.html http://www.shnenglu.com/billhsu/comments/110683.html http://www.shnenglu.com/billhsu/archive/2010/03/27/110683.html#Feedback 3 http://www.shnenglu.com/billhsu/comments/commentRss/110683.html http://www.shnenglu.com/billhsu/services/trackbacks/110683.html 首先Qfstream竟然在中文\径这U东西上不支持,|上也可以看到许多实现方法,但有的方法其实ƈ不是太好?br />我觉得这样做最单:setlocale(LC_ALL, "" ); // 讄成当前语a环境 ofstream out (filename); // 打开文g setlocale(LC_CTYPE, 0 );
q有Qfstream的getline也有问题Q对于那些\n \r I 什么的都没考虑Q用h会出错?br />在网上看C个函数可以完解册个问题:bool readline(ifstream & infile, string & textline) { while (getline(infile, textline, ' \n ' )) { int prev_pos = 0 ; // 最开始有效字W位|? int post_pos = 0 ; // 最后有效字W位|?br /> // 下面的@环语句能够用textline.find_first_not_of(filter,pos)来处?Z效率考虑本处使用q样的算?/span> while (textline[prev_pos] == ' ' || textline[prev_pos] == ' \t ' || textline[prev_pos] == ' \r ' ) // qo开始空?/span> prev_pos ++ ; if (textline[prev_pos] == ' \0 ' ) continue ; // 假如是空白行则再M行进行处? else { post_pos= textline.length() - 1 ; while (textline[post_pos] == ' ' || textline[post_pos] == ' \t ' || textline[post_pos] == ' \r ' ) // qo最后的I白 { post_pos -- ; } textline = textline.substr(prev_pos,post_pos + 1 - prev_pos); return true ; // 成功d一有效?/span> } } return false ; // d文的末?/span>}
我根据上面这个函?重蝲了一个char* 版的Q?br />bool readline(ifstream & infile, char * textline) { while (infile.getline(textline, 32 )) { int prev_pos = 0 ; // 最开始有效字W位|?/span> int post_pos = 0 ; // 最后有效字W位|? string str = textline; // 下面的@环语句能够用textline.find_first_not_of(filter,pos)来处?Z效率考虑本处使用q样的算?/span> while (str[prev_pos] == ' ' || str[prev_pos] == ' \t ' || str[prev_pos] == ' \r ' ) // qo开始空?/span> prev_pos ++ ; if (str[prev_pos] == ' \0 ' ) continue ; // 假如是空白行则再M行进行处?/span> else { post_pos= str.length() - 1 ; while (str[post_pos] == ' ' || str[post_pos] == ' \t ' || str[post_pos] == ' \r ' ) // qo最后的I白 { post_pos -- ; } string str2 = str.substr(prev_pos,post_pos + 1 - prev_pos); strcpy(textline,str2.c_str()); return true ; // 成功d一有效?/span> } } return false ; // d文的末?/span>}
]]> GPU水面模拟 http://www.shnenglu.com/billhsu/archive/2010/03/23/110376.htmlBill Hsu Bill Hsu Tue, 23 Mar 2010 12:59:00 GMT http://www.shnenglu.com/billhsu/archive/2010/03/23/110376.html http://www.shnenglu.com/billhsu/comments/110376.html http://www.shnenglu.com/billhsu/archive/2010/03/23/110376.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/110376.html http://www.shnenglu.com/billhsu/services/trackbacks/110376.html 效果比较单,只是模拟了下水面的反效果。折与FresnelpL没有考虑?br /> 水面模拟大致需要分q么几步Q?br />1.剪裁掉水面以下的点[gpu里的clipplane要注意{换到Clip Space]Q?br />摄像机攑ֈ同原摄像机关于水面对U的位置Q比如原来摄像机?x,y,z)Q?br />此时p把摄像机攑֜(x,-y,z)Qup向量也要讄成向下的?br />再把场景渲染到Render Target的纹理上(我用的纹理大是256*256)Q不知道Z么Render Target的纹理大不能超q窗口大,过的话渲染会出错,知道的大大告诉我一下哈?br /> 于是Q就得到了这样一个纹理: 2.上面得到的U理与水面的点对应. 把Vertex Shader中乘q变换矩阵后的坐标传到Pixel Shader, 在PS中计?br /> float2 clipspace = input.Coord.xy / input.Coord.w; clipspace.x=((clipspace.x * 0.5f) + 0.5f); clipspace.y = ((clipspace.y * -0.5f) + 0.5f); clipspace.x=1-clipspace.x;
既可以让水面点与纹理对应,然后再想办法把纹理坐标扰乱来模拟水面波动?br /> 3.再渲染一ơ场景就可以了?br /> 大家也可以参考下Azure的水面渲染源代码Q?a temp_href=" http://www.azure.com.cn/article.asp?id=186" href="%20http://www.azure.com.cn/article.asp?id=186"> http://www.azure.com.cn/article.asp?id=186 ]]>可编E管道下的剪裁^?/title> http://www.shnenglu.com/billhsu/archive/2010/01/20/106088.htmlBill Hsu Bill Hsu Wed, 20 Jan 2010 14:00:00 GMT http://www.shnenglu.com/billhsu/archive/2010/01/20/106088.html http://www.shnenglu.com/billhsu/comments/106088.html http://www.shnenglu.com/billhsu/archive/2010/01/20/106088.html#Feedback 2 http://www.shnenglu.com/billhsu/comments/commentRss/106088.html http://www.shnenglu.com/billhsu/services/trackbacks/106088.html
剪裁q面
(Clip Plane)
在图形学领域有着重要的作用,比如水面模拟中,渲染折射U理Ӟ我们必d水面以上的顶炚w过剪裁q面剪裁掉?/span>
在过ȝ固定渲染道时代Q剪裁^面的实现较ؓ单,比如?/span>
DirectX 9
中,可以先设定剪裁^面在世界坐标pM的方E?/span>
(ax+by+cz+d=0)
Q再调用
SetClipPlane(DWORD Index,CONST float * pPlane)
q个
API
函数可以了?/span>
附上例子E序Q?/span>
vPosition=D3DXVECTOR3(0,0,0);
//
q面上一个点
vNormal=D3DXVECTOR3(0,1,0);
//
法向?span>
D3DXPlaneFromPointNormal( &clipplane, &vPosition, &vNormal );
//
生成剪裁q面
m_pDevice()->SetClipPlane( 0, (
float
*)clipplane);
然而,在现在的可编E管?/span>
(programmable pipeline)
下,讄的剪裁^面会被在剪裁坐标pM处理Q而不是在世界坐标pM?/span>
解决q个问题的方法有Q?br />
1Q?l要剪裁的顶点做标记Q在Pixel Shader中把它剪裁掉?br />
2Q?使用q斜q面裁剪QOblique Near-Plane ClippingQ,即修Ҏq阵,要剪裁的顶Ҏ在视截体之外Q从而避免了该顶点的l制?br />
3Q?修改q面方程Q之从世界坐标p{换到剪裁坐标pR?span>
上述Ҏ中,W一U和W二U效率ƈ不高Q在Pixel Shader 中剪裁没有减Q何不必要的顶点处理,而计近斜^面裁剪矩阵较为繁琐。所以,Ҏ三是最佳选择?/span> 要将一个^面从世界坐标p{换到剪裁坐标p,必须求出q个变换矩阵?/span>
讑^面方E?/span>ax+by+cz+d=0 Q用一?/span>4 l向量来 n 表示 (a,b,c,d) Q设q面上有个点 p:(x,y,z,1) 。根据^面方E的定义Q有Q?/span>
n T p = ax + by + cz + d = 0
讄?/span>R 可以让点 P 从世界坐标系转换到剪裁坐标系Q矩?/span>Q 可以让^?/span>n 实现同样的变换。那么,有:
p '= R p
n' = Q n
其中 p' ?/span>n' 分别是{换后的点与^面?/span>
n ' T p' = 0
(Q n )T (R p ) = 0 n T Q T R p = 0如果Q?/span>Q T R = I
那么Q?/span>
n T Q T R p = n T I p = n T p = 0
于是Q?/span>
Q T = R -1
Q = (R -1 )T
?/span>DirectX 3D 中,一个点从世界坐标系转换到剪裁坐标系Q所用的矩阵察矩阵与投媄矩阵的乘U,卻I
D3DXMATRIX TranMatrix = matView*matProj;
(TranMatrix 为所求的变换矩阵Q?span>matView ?span>matProj
分别?/span>观察矩阵与投q?/span>)
附上?/span>D3D 中变换的完整代码Q?/span>
D3DXPLANE tempPlane = clipplane;
D3DXPlaneNormalize(&tempPlane, &tempPlane);
D3DXMATRIX TranMatrix = matView*matProj;
D3DXMatrixInverse(&TranMatrix, NULL, &TranMatrix);
D3DXMatrixTranspose(&TranMatrix, &TranMatrix);
D3DXPlaneTransform(&tempPlane, &tempPlane, &TranMatrix);
参考资料:
1.Back Face Culling Notes ,Jordan Smith (University of California, Berkeley)
http://www.cs.berkeley.edu/~ug/slide/pipeline/assignments/backfacecull.shtml
2.GameDev Forum
http://www.gamedev.net/community/forums/topic.asp?topic_id=402381
3.Oblique Near-Plane Clipping with Orthographic Camera ,Aras
http://aras-p.info/texts/obliqueortho.html
]]>矩阵求逆代?/title> http://www.shnenglu.com/billhsu/archive/2009/12/11/103010.htmlBill Hsu Bill Hsu Fri, 11 Dec 2009 14:23:00 GMT http://www.shnenglu.com/billhsu/archive/2009/12/11/103010.html http://www.shnenglu.com/billhsu/comments/103010.html http://www.shnenglu.com/billhsu/archive/2009/12/11/103010.html#Feedback 7 http://www.shnenglu.com/billhsu/comments/commentRss/103010.html http://www.shnenglu.com/billhsu/services/trackbacks/103010.html
写个带输出算逆矩늚步骤的矩阉|逆程序,希望l即或正在学线代的同学一Ҏѝ?nbsp; 阅读全文 ]]> 发日志纪念~~W一ơ写导出插g http://www.shnenglu.com/billhsu/archive/2009/11/25/101921.htmlBill Hsu Bill Hsu Wed, 25 Nov 2009 11:25:00 GMT http://www.shnenglu.com/billhsu/archive/2009/11/25/101921.html http://www.shnenglu.com/billhsu/comments/101921.html http://www.shnenglu.com/billhsu/archive/2009/11/25/101921.html#Feedback 2 http://www.shnenglu.com/billhsu/comments/commentRss/101921.html http://www.shnenglu.com/billhsu/services/trackbacks/101921.html
今天l于把模型导出插件最基本的功?-导出|格l写好了?/p>
c++和max sdk一L的感觉很怪,pȝ崩溃了Nơ,不过Qȝ能导出网g~
有图有真相,截图U念
(注意Q模型是从value的csol中弄出来?
在d3d中渲染导出的模型B
在d3d中渲染导出的模型B
我的模型导出插gB
导出数据hQ?/p>
[q是一个带贴图的立方体的导出数据]
8// 8个顶?br />
-6.70302 -21.2068 -5.46039
17.1883 -6.46757 0.162097
-22.4049 2.22378 -0.162097
1.48644 16.963 5.46039
-8.48039 -28.3257 20.7542
15.411 -13.5865 26.3767
-24.1823 -4.89514 26.0525
-0.290929 9.84411 31.675
12// 12个纹理坐?br />
0 1 0
1 1 0
0 0 0
1 0 0
0 1 0
1 1 0
0 0 0
1 0 0
0 1 0
1 1 0
0 0 0
1 0 0
12// 12个面引烦
0 9 2 11 3 10
3 10 1 8 0 9
4 8 5 9 7 11
7 11 6 10 4 8
0 4 1 5 5 7
5 7 4 6 0 4
1 0 3 1 7 3
7 3 5 2 1 0
3 4 2 5 6 7
6 7 7 6 3 4
2 0 0 1 4 3
4 3 6 2 2 0
]]> DirectX 3D 讑֤丢失(lost device)的处?/title> http://www.shnenglu.com/billhsu/archive/2009/10/17/98823.htmlBill Hsu Bill Hsu Sat, 17 Oct 2009 05:10:00 GMT http://www.shnenglu.com/billhsu/archive/2009/10/17/98823.html http://www.shnenglu.com/billhsu/comments/98823.html http://www.shnenglu.com/billhsu/archive/2009/10/17/98823.html#Feedback 2 http://www.shnenglu.com/billhsu/comments/commentRss/98823.html http://www.shnenglu.com/billhsu/services/trackbacks/98823.html
低手交流Q高手勿?br /> 当初觉得DX中设备丢失很讨厌Q差点就投奔OpenGL了?br />
不过现在发现其实也没那么ȝ啦,写点东西Q给不清?/font>
讑֤丢失怎么处理的同学参考下?br /> 在创建时使用D3DPOOL_MANAGED标志的资源可以不需要重新蝲入,但D3DPOOL_DEFAULT加蝲的资源就需要先释放Q后重徏?br /> 通常需要这样处理的有ID3DXFont和ID3DXSpriteQ?X模型什么的׃需要?br />在发现设备丢失时Q我们要调用 OnLostDevice( void ) 函数让D3DPOOL_DEFAULT加蝲的资源释放掉?br />好在ID3DXFont和ID3DXSprite有设备丢失处理函敎ͼ直接调用好?div style="border: 1px solid rgb(204, 204, 204); padding: 4px 5px 4px 4px; background-color: rgb(238, 238, 238); font-size: 13px; width: 98%;">void OnLostDevice( void ) { m_sprite -> OnLostDevice(); m_font -> OnLostDevice(); } 可是Q怎么知道讑֤丢失了呢Q?br />如果讑֤丢失QPresent()函数׃“出问题”,q回值是D3DERR_DEVICELOST?br />m_pIDirect3DDevice -> EndScene(); HRESULT hr; hr = m_pIDirect3DDevice -> Present(NULL, NULL, NULL, NULL); if (hr == D3DERR_DEVICELOST) { if (m_pIDirect3DDevice -> TestCooperativeLevel() == D3DERR_DEVICENOTRESET) { OnLostDevice(); OnResetDevice(); } }
TestCooperativeLevel() == D3DERR_DEVICENOTRESETӞ可以恢复设备了?br />于是Q我们调?/span>OnLostDevice( ) 让D3DPOOL_DEFAULT加蝲的资源释放掉Q之后,调用OnResetDevice()来恢复设备就可以了?br /> 怎么恢复讑֤呢?void OnResetDevice( void ) { if (FAILED(m_pIDirect3DDevice -> Reset( & d3dpp))) { return ; } m_sprite -> OnResetDevice(); m_font -> OnResetDevice(); InitDevice(); }
先让D3D讑֤resetQ然后调?/span>ID3DXFont和ID3DXSprite的恢复函敎ͼ最后,需要把D3D讑֤中的状态啊Q矩阵变换啊q些重新讄下就完成了,也就是调?/span>InitDevice()?br />void InitDevice() { m_pIDirect3DDevice -> SetRenderState( D3DRS_ZENABLE, TRUE ); m_pIDirect3DDevice -> SetRenderState( D3DRS_AMBIENT, 0xffffffff ); m_pIDirect3DDevice -> SetSamplerState( 0 , D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); m_pIDirect3DDevice -> SetSamplerState( 0 , D3DSAMP_MINFILTER, D3DTEXF_LINEAR); m_pIDirect3DDevice -> SetSamplerState( 0 , D3DSAMP_MIPFILTER, D3DTEXF_POINT); D3DXMatrixPerspectiveFovLH( & matProj, D3DX_PI / 4 , 1.0f , 1.0f , 1000.0f ); m_pIDirect3DDevice -> SetTransform( D3DTS_PROJECTION, & matProj ); vEyeVec = D3DXVECTOR3( 0.0f , 0.0f , - 1.0f ); vLookatVec = D3DXVECTOR3( 0.0f , 0.0f , 0.0f ); vUpVec = D3DXVECTOR3( 0.0f , 1.0f , 0.0f ); D3DXMatrixLookAtLH( & matView, & vEyeVec, & vLookatVec, & vUpVec ); m_pIDirect3DDevice -> SetTransform( D3DTS_VIEW, & matView ); }
啊,q样讑֤丢失处理好?br /> // tag:DirectX 3D d3d lost device TestCooperativeLevel OnLostDevice 恢复讑֤ 讑֤丢失 DeviceLost ]]> 自己写的Rap3d 引擎 开源发布啦 http://www.shnenglu.com/billhsu/archive/2009/07/25/91123.htmlBill Hsu Bill Hsu Sat, 25 Jul 2009 07:00:00 GMT http://www.shnenglu.com/billhsu/archive/2009/07/25/91123.html http://www.shnenglu.com/billhsu/comments/91123.html http://www.shnenglu.com/billhsu/archive/2009/07/25/91123.html#Feedback 5 http://www.shnenglu.com/billhsu/comments/commentRss/91123.html http://www.shnenglu.com/billhsu/services/trackbacks/91123.html 我在sourceforge上申请了开源项目,在那里可以下载到Rap3d SDK.http://rap3d.sf.net/
Rap3d SDK 中有引擎的用说明和几个例子Q上手很快的?br />What Rap3d can do?
1.Display 3d models
2.Bill Board,Sprite,Animation..
3.Music playing
4.Draw text on screen
http://rap3d.sf.net/
]]> Rap3d更新 http://www.shnenglu.com/billhsu/archive/2009/06/23/88346.htmlBill Hsu Bill Hsu Tue, 23 Jun 2009 02:12:00 GMT http://www.shnenglu.com/billhsu/archive/2009/06/23/88346.html http://www.shnenglu.com/billhsu/comments/88346.html http://www.shnenglu.com/billhsu/archive/2009/06/23/88346.html#Feedback 1 http://www.shnenglu.com/billhsu/comments/commentRss/88346.html http://www.shnenglu.com/billhsu/services/trackbacks/88346.html
增加?TextureManager? BillBoard动画播放,方便渲染爆炸效果 ]]> 游戏中CPU使用率的控制 http://www.shnenglu.com/billhsu/archive/2009/06/12/87472.htmlBill Hsu Bill Hsu Fri, 12 Jun 2009 04:00:00 GMT http://www.shnenglu.com/billhsu/archive/2009/06/12/87472.html http://www.shnenglu.com/billhsu/comments/87472.html http://www.shnenglu.com/billhsu/archive/2009/06/12/87472.html#Feedback 18 http://www.shnenglu.com/billhsu/comments/commentRss/87472.html http://www.shnenglu.com/billhsu/services/trackbacks/87472.html 应该用Sleep(1)把多余的片段q给CPU, 像这Pwhile ( true ) { DWORD start_time = GetTickCount(); if (PeekMessage( & msg,NULL, 0 , 0 ,PM_REMOVE)) { if (msg.message == WM_QUIT) break ; TranslateMessage( & msg); DispatchMessage( & msg); } update( float (GetTickCount() - start_time)); while ((GetTickCount() - start_time) < 30 ) Sleep( 1 ); }
update(float timeDelta)是游戏逻辑与画面更新的函数?br />效果图: ]]> 3D引擎计划 http://www.shnenglu.com/billhsu/archive/2009/06/10/87356.htmlBill Hsu Bill Hsu Wed, 10 Jun 2009 13:15:00 GMT http://www.shnenglu.com/billhsu/archive/2009/06/10/87356.html http://www.shnenglu.com/billhsu/comments/87356.html http://www.shnenglu.com/billhsu/archive/2009/06/10/87356.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/87356.html http://www.shnenglu.com/billhsu/services/trackbacks/87356.html
其实也就是把一些类装一下,让开发更l,以开源和实用为第一准则?br /> ]]> 用GDI实现3D http://www.shnenglu.com/billhsu/archive/2008/12/27/70517.htmlBill Hsu Bill Hsu Sat, 27 Dec 2008 09:18:00 GMT http://www.shnenglu.com/billhsu/archive/2008/12/27/70517.html http://www.shnenglu.com/billhsu/comments/70517.html http://www.shnenglu.com/billhsu/archive/2008/12/27/70517.html#Feedback 1 http://www.shnenglu.com/billhsu/comments/commentRss/70517.html http://www.shnenglu.com/billhsu/services/trackbacks/70517.html 不过x看,好像实现h也ƈ不难。。?br />和所有基?DE序一P先把视椎变换为单位立方体Q?br /> 变换矩阵为: 当然QDirectX和OpenGL里都有现成的函数Q?br />// OpenGL void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar); // DirectX D3DXMatrixPerspectiveFovLH( D3DXMATRIX * pOut, FLOAT fovY, FLOAT Aspect, FLOAT zn, FLOAT zf );
单位立方体中的点正交投媄得到?x,y,z)*视口变换矩阵 得到 (x',y',z')?br />(x',y')对应屏幕点,z'为其深度Q用于点的竞争?br />把每个三角面匚wU理用GDI基本函数d来就可以了?br /> CSDN的那个程?br /> ]]>A* (A-star A?寻\法 http://www.shnenglu.com/billhsu/archive/2008/11/01/65700.htmlBill Hsu Bill Hsu Sat, 01 Nov 2008 10:19:00 GMT http://www.shnenglu.com/billhsu/archive/2008/11/01/65700.html http://www.shnenglu.com/billhsu/comments/65700.html http://www.shnenglu.com/billhsu/archive/2008/11/01/65700.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/65700.html http://www.shnenglu.com/billhsu/services/trackbacks/65700.html 仔细看了看gamedev.net的一片文?A* Pathfinding for Beginners
http://www.gamedev.net/reference/articles/article2003.asp
)Q对A*更了解了一点,写点东西记录一下?br />A*是一U启发式的算法,所谓的"启发?Q就是对每一个搜索的位置q行评估Q也是把找的位|离目标的距d成找点的一个依据,然后猜测q个Ҏ否最?"启发?是猜测)?br /> Z扑ֈ最佳的那个?br />可以规定Q?br />G = 从v点,沿着产生的\径,Ud到网g指定Ҏ的距R?br />H = 从网g那个ҎUd到终点B的预估移动距R?br /> F = G + H F最的点可以认为是该选的炏V?br />引用 一下原文的译Q?br />我们令水qx者垂直移动的耗费?0Q对角线方向耗费?4。我们取q些值是因ؓ沿对角线的距L沿水qx垂直Ud耗费的的根号2Q别怕)Q或者约1.414倍。ؓ了简化,我们?0?4q似。比例基本正,同时我们避免了求根运和数?br /> 既然我们在计沿特定路径通往某个Ҏ的G|求值的Ҏ是取它父节点的G|然后依照它相对父节点是对角线方向或者直角方?非对角线)Q分别增?4?0。例子中q个Ҏ的需求会变得更多Q因为我们从LҎ以外获取了不止一个方根{?br /> H值可以用不同的方法估。我们这里用的Ҏ被称为曼哈顿ҎQ它计算从当前格到目的格之间水^和垂直的Ҏ的数量dQ忽略对角线方向。然后把l果乘以10。这被成为曼哈顿Ҏ是因为它看v来像计算城市中从一个地方到另外一个地方的街区敎ͼ在那里你不能沿对角线方向I过街区。很重要的一点,我们忽略了一切障物。这是对剩余距离的一个估,而非实际|q也是这一Ҏ被称为启发式的原因。想知道更多Q你可以在这里找到方E和额外的注解?br />
W一步搜索的l果可以在下面的图表中看到。F,G和H的评分被写在每个Ҏ里。正如在紧挨起始格右侧的Ҏ所表示的,F被打印在左上角,G在左下角QH则在右下角?/span>引用 一下原文的译Q?/span> 我们做如下操作开始搜索: 1 Q从点A开始,q且把它作ؓ待处理点存入一个“开启列表”。开启列表就像一张购物清单。尽现在列表里只有一个元素,但以后就会多h。你的\径可能会通过它包含的ҎQ也可能不会。基本上Q这是一个待查方格的列表?br /> 2 Q寻找v点周围所有可到达或者可通过的方|跌有墙Q水Q或其他无法通过地Ş的方根{也把他们加入开启列表。ؓ所有这些方g存点A作ؓ“父Ҏ”。当我们xq\径的时候,父方格的资料是十分重要的。后面会解释它的具体用途?br /> 3 Q从开启列表中删除点AQ把它加入到一个“关闭列表”,列表中保存所有不需要再ơ检查的Ҏ?br /> Zl箋搜烦Q我们简单的从开启列表中选择F值最低的Ҏ。然后,寚w中的方格做如下处理Q?br /> 4 Q把它从开启列表中删除Q然后添加到关闭列表中?br /> 5 Q检查所有相L子。蟩q那些已l在关闭列表中的或者不可通过?有墙Q水的地形,或者其他无法通过的地?Q把他们dq开启列表,如果他们q不在里面的话。把选中的方g为新的方格的父节炏V?br /> 6 Q如果某个相L已经在开启列表里了,查现在的q条路径是否更好。换句话_查如果我们用新的路径到达它的话,G值是否会更低一些。如果不是,那就什么都不做?br /> 另一斚wQ如果新的G值更低,那就把相L格的父节Ҏ为目前选中的方|在上面的图表中,把箭头的方向改ؓ指向q个ҎQ。最后,重新计算F和G的倹{如果这看v来不够清晎ͼ你可以看下面的图C?/span>
q样可以找到最佌\径了?br /> ]]> 游戏框架 http://www.shnenglu.com/billhsu/archive/2008/10/18/64311.htmlBill Hsu Bill Hsu Sat, 18 Oct 2008 09:46:00 GMT http://www.shnenglu.com/billhsu/archive/2008/10/18/64311.html http://www.shnenglu.com/billhsu/comments/64311.html http://www.shnenglu.com/billhsu/archive/2008/10/18/64311.html#Feedback 17 http://www.shnenglu.com/billhsu/comments/commentRss/64311.html http://www.shnenglu.com/billhsu/services/trackbacks/64311.html 可以把图形渲染,逻辑处理Q网l联机等都做成差不多的模块,然后加到框架Q这样好理一炏V?br />class CFramework { public : CFramework(); ~ CFramework(); void init(); void update(); void Shutdown(); void add(Module * module); // 加入模块 };
Module 是一个纯虚函数类class Module { public : virtual void init(); virtual void update( float dt); };
囑Ş渲染Q逻辑处理Q网l联机模块就可以q行了?img src ="http://www.shnenglu.com/billhsu/aggbug/64311.html" width = "1" height = "1" /> ]]> 栈对象和堆对?/title> http://www.shnenglu.com/billhsu/archive/2008/10/10/63673.htmlBill Hsu Bill Hsu Fri, 10 Oct 2008 09:36:00 GMT http://www.shnenglu.com/billhsu/archive/2008/10/10/63673.html http://www.shnenglu.com/billhsu/comments/63673.html http://www.shnenglu.com/billhsu/archive/2008/10/10/63673.html#Feedback 0 http://www.shnenglu.com/billhsu/comments/commentRss/63673.html http://www.shnenglu.com/billhsu/services/trackbacks/63673.html 什么时候该用 Object object ; 什么时候该用 Object * object ; object = new Object();
感觉看v来没什么区别,其实不一P前一个是栈对象,后一个是堆对象?br /> 引用一下别人对栈对象、堆对象的解释: 栈对象的优势是在适当的时候自动生成,又在适当的时候自动销毁,不需要程序员操心Q而且栈对象的创徏速度一般较堆对象快Q因为分配堆对象Ӟ会调用?/span>operator new操作Q?/span>operator new会采用某U内存空间搜索算法,而该搜烦q程可能是很Ҏ间的Q生栈对象则没有这么麻烦,它仅仅需要移动栈指针就可以了。但是要注意的是Q通常栈空间容量比较小Q一般是1MB?MBQ所以体U比较大的对象不适合在栈中分配。特别要注意递归函数中最好不要用栈对象Q因为随着递归调用深度的增加,所需的栈I间也会U性增加,当所需栈空间不够时Q便会导致栈溢出Q这样就会生运行时错误?br /> 堆对象,其生时d销毁时刻都要程序员_定义Q也是_E序员对堆对象的生命h完全的控制权。我们常帔R要这L对象Q比如,我们需要创Z个对象,能够被多个函数所讉KQ但是又不想使其成ؓ全局的,那么q个时候创Z个堆对象无疑是良好的选择Q然后在各个函数之间传递这个堆对象的指针,便可以实现对该对象的׃n。另外,相比于栈I间Q堆的容量要大得多。实际上Q当物理内存不够Ӟ如果q时q需要生成新的堆对象Q通常不会产生q行旉误,而是pȝ会用虚拟内存来扩展实际的物理内存?/span>
所?br />当你知道你要使用的类型拥有准数量时使用 Object object ; 当你不知道你要创建的cd有多个时?Object * object ; object = new Object(); ]]> 四元数入?/title> http://www.shnenglu.com/billhsu/archive/2008/09/30/63099.htmlBill Hsu Bill Hsu Tue, 30 Sep 2008 11:34:00 GMT http://www.shnenglu.com/billhsu/archive/2008/09/30/63099.html http://www.shnenglu.com/billhsu/comments/63099.html http://www.shnenglu.com/billhsu/archive/2008/09/30/63099.html#Feedback 1 http://www.shnenglu.com/billhsu/comments/commentRss/63099.html http://www.shnenglu.com/billhsu/services/trackbacks/63099.html 但我的那?D囑Ş学书上,在没讲四元数是干什么的之前Q就列了几张U的公式Q?br />大概因ؓ自己q在上高中,不知道的太多Q看了半天没看懂。。?br />l于Q在gameres上看C某强人翻译的一个?元数宝典 ”(原文是日本h写的。。。)Q感觉很好,分n下?br />★旋转篇Q?br /> 我将说明使用了四元数Qsi yuan shu, quaternionQ的旋{的操作步?br />Q?/span>Q?/span>Q四元数的虚部,实部和写?br />所谓四元数Q就是把4个实数组合v来的东西?br />4个元素中Q一个是实部Q其?个是虚部?br />比如Q叫做Q的四元数Q实部t而虚部是x,y,z构成Q则像下面这样写?br />Q = (t; x, y, z) 又,使用向量 V = (x,y,z)Q?br />Q = (t; V) 也可以这么写?br /> 正规地用虚数单位i,j,k的写法的话, Q = t + xi + yj + zk 也这样写Q不q,我不大?br /> Q?/span>Q?/span>Q四元数之间的乘?br />虚数单位之间的乘法?br />ii = - 1 , ij = - ji = k (其他的组合也是@环地以下同文) 有这么一U规则。(我总觉得,q就像是向量U(外积Q,对吧Q?br />用这个规则一点点地计很ȝQ所以请用像下面q样的公式计?br /> A = (a; U) B = (b; V) AB = (ab - U·V; aV + bU + U×V) 不过Q“U·V”是内积Q「U×V」是外积的意思?br />注意Q一般AB <> BA所以乘法的左右要注意! Q?/span>3 Q?ơ元的坐标的四元数表C?br />如要某坐标(x,y,z)用四元数表示Q?br />P = ( 0 ; x, y, z) 则要q么写?br /> 另外Q即使实部是零以外的|下文的结果也一栗用零的话省事所以我推荐?br /> Q?/span>Q?/span>Q旋转的四元数表C?br />以原点ؓ旋{中心Q旋转的轴是(, β, ) Q但 ^ 2 + β ^ 2 + ^ 2 = 1 Q, Q右手系的坐标定义的话,望向向量(, β, )的前q方向反旉圎ͼ 转θ角的旋转,用四元数表示是Q?br />Q = (cos(θ / 2 ); sin(θ / 2 ), β sin(θ / 2 ), sin(θ / 2 )) R = (cos(θ / 2 ); - sin(θ / 2 ), - β sin(θ / 2 ), - sin(θ / 2 )) (另外R 叫 Q 的共轭四元数。) 那么Q如要实行旋转,则?font color="#ff6600">R P Q = ( 0 ; {案) 请像q样三明d地计。这个值的虚部是旋{之后的点的坐标倹{?br /> Q另外,实部应该为零。请验算看看Q?/span>
例子代码/// Quaternion.cpp /// (C) Toru Nakata, toru-nakata@aist.go.jp /// 2004 Dec 29 #include < math.h > #include < iostream.h > /// Define Data type typedef struct { double t; // real-component double x; // x-component double y; // y-component double z; // z-component } quaternion; /// / Bill 注:Kakezan 在日语里?“乘法”的意?/b> quaternion Kakezan(quaternion left, quaternion right) { quaternion ans; double d1, d2, d3, d4; d1 = left.t * right.t; d2 = - left.x * right.x; d3 = - left.y * right.y; d4 = - left.z * right.z; ans.t = d1 + d2 + d3 + d4; d1 = left.t * right.x; d2 = right.t * left.x; d3 = left.y * right.z; d4 = - left.z * right.y; ans.x = d1 + d2 + d3 + d4; d1 = left.t * right.y; d2 = right.t * left.y; d3 = left.z * right.x; d4 = - left.x * right.z; ans.y = d1 + d2 + d3 + d4; d1 = left.t * right.z; d2 = right.t * left.z; d3 = left.x * right.y; d4 = - left.y * right.x; ans.z = d1 + d2 + d3 + d4; return ans; } /// / Make Rotational quaternion quaternion MakeRotationalQuaternion( double radian, double AxisX, double AxisY, double AxisZ) { quaternion ans; double norm; double ccc, sss; ans.t = ans.x = ans.y = ans.z = 0.0 ; norm = AxisX * AxisX + AxisY * AxisY + AxisZ * AxisZ; if (norm <= 0.0 ) return ans; norm = 1.0 / sqrt(norm); AxisX *= norm; AxisY *= norm; AxisZ *= norm; ccc = cos( 0.5 * radian); sss = sin( 0.5 * radian); ans.t = ccc; ans.x = sss * AxisX; ans.y = sss * AxisY; ans.z = sss * AxisZ; return ans; } /// / Put XYZ into quaternion quaternion PutXYZToQuaternion( double PosX, double PosY, double PosZ) { quaternion ans; ans.t = 0.0 ; ans.x = PosX; ans.y = PosY; ans.z = PosZ; return ans; } /// // main int main() { double px, py, pz; double ax, ay, az, th; quaternion ppp, qqq, rrr; cout << " Point Position (x, y, z) " << endl; cout << " x = " ; cin >> px; cout << " y = " ; cin >> py; cout << " z = " ; cin >> pz; ppp = PutXYZToQuaternion(px, py, pz); while ( 1 ) { cout << " \nRotation Degree ? (Enter 0 to Quit) " << endl; cout << " angle = " ; cin >> th; if (th == 0.0 ) break ; cout << " Rotation Axis Direction ? (x, y, z) " << endl; cout << " x = " ; cin >> ax; cout << " y = " ; cin >> ay; cout << " z = " ; cin >> az; th *= 3.1415926535897932384626433832795 / 180.0 ; /// Degree -> radian; qqq = MakeRotationalQuaternion(th, ax, ay, az); rrr = MakeRotationalQuaternion( - th, ax, ay, az); ppp = Kakezan(rrr, ppp); ppp = Kakezan(ppp, qqq); cout << " \nAnser X = " << ppp.x << " \n Y = " << ppp.y << " \n Z = " << ppp.z << endl; } return 0 ; }
http://staff.aist.go.jp/toru-nakata/quaternion.html http://bbs.gameres.com/showthread.asp?threadid=73511 ]]> 经元网l的入门 http://www.shnenglu.com/billhsu/archive/2008/08/30/60455.htmlBill Hsu Bill Hsu Sat, 30 Aug 2008 12:08:00 GMT http://www.shnenglu.com/billhsu/archive/2008/08/30/60455.html http://www.shnenglu.com/billhsu/comments/60455.html http://www.shnenglu.com/billhsu/archive/2008/08/30/60455.html#Feedback 2 http://www.shnenglu.com/billhsu/comments/commentRss/60455.html http://www.shnenglu.com/billhsu/services/trackbacks/60455.html
2001 q?nbsp; 6 ?nbsp; 01 ?br> 经|络也许是计机计算的将来,一个了解它的好Ҏ是用一个它可以解决的难题来说明。假讄?nbsp; 500 个字W的代码D,您知道它们是 C、C ++ 、Java 或?nbsp;Python。现在构造一个程序,来识别编写这D代码的语言。一U解x案是构造一个能够学习识别这些语a的神l网l。这文章讨Z经|络的基本功能以及构造神l网l的ҎQ这样就可以在编码时应用它们了?/span>
Bill注:解释一下,q文章是? ( _ . = ; " , ' * / { } : - 0 + 1 [ ] q?0个特D符号出现频?人工经元的判断来识?span style="color: #000000;">代码D?/span>?nbsp;C、C ++ 、Java 或?nbsp;Python
Ҏ一个简化的l计Qh脑由百亿条神l组??
每条经q_q结到其它几千条经。通过q种q结方式Q神l可以收发不同数量的能量。神l的一个非帔R要的功能是它们对能量的接受ƈ不是立即作出响应Q?
是将它们累加hQ当q个累加的d辑ֈ某个临界阈值时Q它们将它们自己的那部分能量发送给其它的神l。大脑通过调节q些q结的数目和强度q行学习。尽?
q是个生物行为的化描q。但同样可以充分有力地被看作是神l网l的模型?/p>
阈值逻辑单元QThreshold Logic
UnitQTLUQ?/span>
理解经|络的第一步是从对抽象生物经开始,q把重点攑֜
阈值逻辑单元QTLUQ?/em>q一特征上。一?
TLU
是一个对象,它可以输入一l加权系数的量,对它们进行求和,如果q个和达到或者超q了某个阈|输出一个量?
让我们用W号标注q些功能Q首先,有输入g及它们的权系敎ͼX
1 ,
X
2 , ..., X
n ?W
1 , W
2,
..., W
n 。接着是求和计出?X
i *W
i
Q生了Ȁ发层 aQ换一U方法表C:
a = (X1 * W1)+(X2 * W2)+...+(Xi * Wi)+...+ (Xn * Wn)
阈值称?theta。最后,输出l果 y。当 a >=theta ?y=1Q反?
y=0。请注意输出可以是连l的Q因为它也可以由一?squash 函数 sQ或
sigmaQ判定,该函数的自变量是 aQ函数值在 0 ?1 之间Qy=s(a)?/p>
?1. 阈值逻辑单元Q带?sigma 函数Q顶部)?cutoff
函数Q底部)
TLU 会分c,假设一?TLU 有两个输入|它们的权pL{于 1Qtheta
值等?1.5。当q个 TLU 输入 <0,0>?lt;0,1>?lt;1,0>
?<1,1> Ӟ它的输出分别?0???。TLU
这些输入分Zl:0 l和 1 l。就像懂得逻辑q接Q布运?
ANDQ的可以cM地将逻辑q接的句子分c那PTLU
也懂得一炚w辑q接之类的东ѝ?/p>
TLU
能够用几何学上的解释来阐明这U现象。它的四U可能输入对应于W卡图的四个点。从{式
X
1 *W
1 + X
2 *W
2 =
thetaQ换句话_也即 TLU
转换其分c行为的点开始,它的炚w分布在曲U?X
2 =
-X
1 + 1.5 上。这个方E的曲线?4
个可能的输入分成了两个对应于 TLU 分类的区域。这?TLU
原理中更为普通的实例。在 TLU 有Q意数目的 N
个输入的情况下,一l可能的输入对应?N
l空间中的一个点集。如果这些点可以被超q面 ?
换句话说Q对应于上面CZ中的U的 N
l的几何外Ş切割Q那么就有一l权pL和一个阈值来定义其分cd好与q个切割相匹配的
TLU?
Bill注:所谓的 Nl空间就是N个输入节?br>
TLU
的学习原?/span>
既然 TLU
懂得分类Q它们就知道素材。神l网l也可假定ؓ可以学习。它们的学习机制是模仿大脑调节神l连l的原理。TLU
通过改变它的权系数和阈值来学习。实际上Q从数学的观点看Q权pL阈值的特征有点武断。让我们回想一下当
SUM(Xi * Wi) >= theta ?TLU 在界点时输出的?1 而不?
0Q这相当于说临界Ҏ出现?SUM(X
i * W
i )+ (-1
* theta) >= 0 的时候。所以,我们可以?-1
看成一个常量输入,它的权系?theta
在学习(或者用技术术语,UCؓ
培训 Q的q程中进行调整。这P?
SUM(X
i * W
i )+ (-1 * theta) >= 0
Ӟy=1Q反?y=0?
在培训过E中Q神l网l输入:
一pd需要分cȝ术语CZ
它们的正分cL者目?/li>
q样的输入可以看成一个向量:<X
1 , X
2 ,
..., X
n , theta, t>Q这?t
是一个目标或者正分cR神l网l用q些来调整权pLQ其目的使培训中的目标与其分cȝ匚w。更切地说Q这是有指导的培训,与之相反的是无指导的培训。前者是Z带目标的CZQ而后者却只是建立在统计分析的基础上。权pL的调整有一个学习规则,一个理惛_的学习算法如下所C:
清单 1.
理想化的学习法
fully_trained = FALSE DO UNTIL (fully_trained): fully_trained = TRUE FOR EACH training_vector = <X1, X2, ..., Xn, theta, target>:: # Weights compared to theta a = (X1 * W1)+(X2 * W2)+...+(Xn * Wn) - theta y = sigma(a) IF y != target: fully_trained = FALSE FOR EACH Wi: MODIFY_WEIGHT(Wi) # According to the training rule IF (fully_trained): BREAK
您或许想知道Q?#8220;哪些培训规则Q?#8221;有很多,不过有一条似乎合理的规则是基于这样一U思想Q即权系数和阈值的调整应该由分?
(t - y) 定。这个规则通过引入 alpha (0 < alpha < 1)
完成。我们把 alpha UCؓ
学习?/em>。W
i 中的更改值等?
(alpha * (t - y)* Xi)。当 alpha 向?0
Ӟ经|络的权pL的调整变得保守一点;?alpha 向?1
Ӟ权系数的调整变得Ȁq。一个用这个规则的经|络UCؓ
感知?/em>Qƈ且这个规则被UCؓ
感知器学习规?/em>。Rosenblatt ?1962 q下的结论是Q如?N
l空间的炚w被超q面切割Q那么感知器的培训算法的应用会最l导致权pL的分配,从而定义了一?
TLUQ它的超q面会进行需要的分割。当ӞZ记v
KeynesQ最l我们都切断了与外界的联p,专心思考。但是在计算旉之外Q我们仍Ȓ危险Q因为我们需要自q经|络对可能输入的I间q行不止一ơ的切割?
文章开始的N举例说明了这个,假设l您 N
个字W的代码D,您知道是 C、C++、Java 或?
Python。难的是构造一个程序来标识~写q段代码的语a。用 TLU
来实现需要对可能的输入空间进行不止一ơ的分割。它需要把I间分成四个区域。每U语a一个区域。把经|络培训成能实现两个切割可完成q种工作。第一个切割将
C/C++ ?Java/Python 分开来,另一个将 C/Java ?C++/Python
分开。一个能够完成这些切割的|络同样可以识别源代码样本中的语a。但是这需要网l有不同l构Q在描述q个不同之处之前Q先来简单地看一下实跉|面的考虑?/p>
?2. 初步的(不完整的Q感知器学习模型
考虑到排除取?N 个字W代码所需的计时_l计?ASCII 码的 32
?127 的范围内可视 ASCII
码字W出现的频率Qƈ在这个统计以及关于代码语a的目标信息的基础上培训神l网l。我们的Ҏ是将字符l计限制?
C、C++、Java ?Python 代码字符库中最常用?20
个非字母数字字符。由于关注Q点运的执行Q我们打用一U规格化因素这
20
字符l计分开来,q以此培训我们的|络。显Ӟ一个结构上的不同是我们的网l有
20
个输入节点,但这是很正常的,因ؓ我们的描q已l暗CZq种可能性。一个更有意思的区别是出C一对中间节点,N1
?N2Q以及输Ҏ量从两个变成了四个(O1 ?O4Q?/p>
我们培?N1Q这样当它一看到 C ?C++Q设|?y1=1Q看?Java ?
PythonQ它设|?y1=0。同理培?N2Q当它一看到 C ?JavaQ设|?
y2=1Q看?C++ ?PythonQ设|?y2=0。此外,N1 ?N2 输?1 ?0
l?Oi。现在如?N1 看到 C ?C++Q而且 N2 看到 C 或?
JavaQ那么难题中的代码是 C。而如?N1 看到 C ?C++QN2 看到 C++ ?
PythonQ那么代码就?C++。这个模式很显而易见。所以假?Oi
已被培训q根据下面表格的情况输出 1 ?0?/p>
映射到输出(作ؓ布尔函数Q的中间节点
N1
N2
O1 (C)
O2 (C++)
O3 (Java)
O4 (Python)
0
0
0
0
0
1
0
1
0
0
1
0
1
0
0
1
0
0
1
1
1
0
0
0
如果q样可行的话Q我们的|络可以从代码CZ中识别出语言了。这个想法很好。但是在实践上却有些难以|信。不q这U解x案预CZ
C/C++ ?Java/Python 输入被一个超q面切割了,同样 C/Java ?
C++/Python
输入被另一个切剌Ӏ这是一个网l培训的解决ҎQ迂回地解决了这个输入空间的设想?/p>
Bill注:看v来很强大
关于 delta
规则
另一U培训的规则叫做 delta 规则。感知器培训规则是基于这样一U思\
?权系数的调整是由目标和输出的差分方程表达式决定。?
delta
规则是基于梯度降落这样一U思\。这个复杂的数学概念可以举个单的例子来表C。从l定的几Ҏ看,向南的那条\径比向东那条更陡些。向东就像从悬崖上掉
下来Q但是向南就是沿着一个略微倾斜的斜坡下来,向西像登一座陡峭的山,而北边则Cq_Q只要慢慢的闲逛就可以了。所以您要寻扄是到辑^地的所有\?
中将陡峭的d减少到最的路径。在权系数的调整中,经|络会扑ֈ一U将误差减少到最的权系数的分配方式?
我们的|络限制为没有隐藏节点,但是可能会有不止一个的输出节点Q设
p 是一l培训中的一个元素,t(p,n) 是相应的输出节点 n
的目标。但是,?y(p,n) ׃上提到的 squash 函数 s 军_Q这?
a(p,n) 是与 p 相关?n 的激zd敎ͼ或者用 (p,n) = s( a(p,n) )
表示Z p 相关的节?n ?squash
q的Ȁzd数。ؓ|络讑֮权系敎ͼ每个 WiQ,也ؓ每个 p ?n 建立
t(p,n) ?y(p,n) 的差分,q就意味着为每?p
讑֮了网l全部的误差。因此对于每l权pL来说有一个^均误差。但?
delta
规则取决于求q_值方法的_度以及误差。我们先不讨论细节问题,只是说一些与某些
p ?n 相关的误差:?* square( t(p,n) - y(p,n) )。现在,对于每个
WiQ^均误差定义如下:
清单 2.
查找q_误差
sum = 0 FOR p = 1 TO M: # M is number of training vectors FOR n = 1 TO N: # N is number of output nodes sum = sum + (1/2 * (t(p,n)-y(p,n))^2) average = 1/M * sum
delta
规则是依据q个误差的定义来定义的。因差是依据那些培训向量来说明的Qdelta
规则是一U获取一个特D的权系数集以及一个特D的向量的算法。而改变权pL会使神l网l的误差最化。我们不需要讨论支持这个算法的微积分学Q只要认ZQ?
Wi 发生的变化都是如下所C就够了Q?/p>
alpha * s'(a(p,n)) * (t(p,n) - y(p,n)) * X(p,i,n).
X(p,i,n) 是输入到节点 n ?p 中的W?i 个元素,alpha
是已知的学习率。最?s'( a(p,n) ) 是与 p 相关的第 n 个节Ҏzȝ
squashing 函数的变化(zQ率Q这是 delta 规则Qƈ?Widrow ?
Stearns 向我们展CZ?
alpha
非常的时候,权系数向量接q某个将误差最化的向量。用于权pL调节的基?
delta 规则的算法就是如此?
梯度降落Q直到误差小到适当的程度ؓ止)
step 1: for each training vector, p, find a(p) step 2: for each i, change Wi by: alpha * s'(a(p,n)) * (t(p,n)-y(p,n)) * X(p,i,n)
q里有一些与感知器算法相区别的重要不同点。显Ӟ在权pL调整的公式下有着完全不同的分析。delta
规则法L在权pL上调_而且q是建立在相对输出的ȀzL式上。最后,q不一定适用于存在隐藏节点的|络?/p>
反向传播 q一法把支?delta
规则的分析扩展到了带有隐藏节点的经|络。ؓ了理解这个问题,设想
Bob l?Alice 讲了一个故事,然后 Alice 又讲l了 TedQTed
查了q个事实真相Q发现这个故事是错误的。现?Ted
需要找出哪些错误是 Bob 造成的而哪些又归咎?
Alice。当输出节点从隐藏节点获得输入,|络发现出现了误差,权系数的调整需要一个算法来扑և整个误差是由多少不同的节炚w成的,|络需要问Q?#8220;是谁让我误入歧途?到怎样的程度?如何弥补Q?#8221;q时Q网l该怎么做呢Q?
?3Q?#8220;代码识别”反向传播的神l网l?
反向传播法同样来源于梯度降落原理,在权pL调整分析中的唯一不同是涉及到
t(p,n) ?y(p,n) 的差分。通常来说 W
i 的改变在于:
alpha * s'(a(p,n)) * d(n) * X(p,i,n)
其中 d(n) 是隐藏节?n 的函敎ͼ让我们来看(1Qn
对Q何给出的输出节点有多大媄响;Q?Q输Ҏw对|络整体的误差有多少影响。一斚wQn
影响一个输点越多,n
造成|络整体的误差也多。另一斚wQ如果输点媄响网l整体的误差少Qn
对输点的影响也相应减。这?d(j)
是对|络的整体误差的基|W(n,j) ?n ?j 造成的媄响,d(j) *
W(n,j) 是这两种影响的d。但?n
几乎L影响多个输出节点Q也怼影响每一个输出结点,q样Qd(n)
可以表示为:
q里 j 是一个从 n
获得输入的输点,联系hQ我们就得到了一个培训规则,W?1
部分Q在隐藏节点 n 和输?j 之间权系数改变,如下所C:
alpha * s'(a(p,n))*(t(p,n) - y(p,n)) * X(p,n,j)
W?2 部分Q在输入节点 i 和输?n
之间权系数改变,如下所C:
alpha * s'(a(p,n)) * sum(d(j) * W(n,j)) * X(p,i,n)
q里每个?n 接收输入的输?j
都不同。关于反向传播算法的基本情况大致如此?/p>
?Wi 初始化ؓ的随机倹{?/p>
使误差小到适当的程度要遵@的步?/span>
W?1
步:输入培训向量?
W?2 步:隐藏节点计算它们的输?
W?3 步:输出节点在第 2 步的基础上计它们的输出?
W?4 步:计算W?3 步所得的l果和期望g间的差?
W?5 步:把第 4 步的l果填入培训规则的第 1 部分?
W?6 步:对于每个隐藏节点 nQ计?d(n)?
W?7 步:把第 6 步的l果填入培训规则的第 2 部分?
通常把第 1 步到W?3 步称?
正向传播 Q把W?4 步到W?7
步称?
反向传播 。反向传播的名字由此而来?
在掌握了反向传播法后,可以来看我们的识别源代码h语言的难题。ؓ了解册个问题,我们提供?
Neil Schemenauer ?Python 模型
bpnn 。用它的模型解决问题真是难以|信的简单,在我们的c?
NN2
里定制了一个类
NN
Q不q我们的改变只是调整了表达方式和整个q程的输出,q没有涉及到法。基本的代码如下所C:
清单 3Q用 bpnn.py
建立一个神l网l?/strong>
# Create the network (number of input, hidden, and training nodes) net = NN2(INPUTS, HIDDEN, OUTPUTS) # create the training and testing data trainpat = [] testpat = [] for n in xrange(TRAINSIZE+TESTSIZE): #... add vectors to each set # train it with some patterns net.train(trainpat, iterations=ITERATIONS, N=LEARNRATE, M=MOMENTUM) # test it net.test(testpat) # report trained weights net.weights()
当然我们需要输入数据,实用E序 code2data.py
提供了这个功能。它的界面很直观Q只要将一堆扩展名各不相同的文件放C个子目录
./code
中,然后q行q个实用E序Qƈ列D那些扩展名作为命令选项。例如:
python code2data.py py c java
您得到的是一?STDOUT
上的向量Q可以把q些向量输入到另一个进E或者重定向C个文Ӟ它的输出如下所C:
清单 4QCode2Data
的输出向?/strong>
0.15 0.01 0.01 0.04 0.07 0.00 0.00 0.03 0.01 0.00 0.00 0.00 0.05 0.00 > 1 0 0 0.14 0.00 0.00 0.05 0.13 0.00 0.00 0.00 0.02 0.00 0.00 0.00 0.13 0.00 > 1 0 0 [...]
让我们回忆一下输入值都是不同特D字W出现的规格化数目,目标|在大于号以后Q是
YES/NOQ它代表包含q些字符的源代码文g的类型,不过对于什么是什么来_q没有非常明昄东西。数字可以是输入或期望的
L?/em>Q这才是最重要的?
下一步是q行实际?code_recognizer.py E序。这需要(?
STDIN
中)像上面一L向量集。这个程序有一个包Q它能够Ҏ实际文g推断出需要多输入节点(计算在内的和期望的)Q选择隐藏节点的数目是一个诀H。对于源代码的识别,6
?8
个隐藏节点似乎工作得很好。如果打试验网l从而发现对于这些不同的选项它是如何做的Q您可以覆盖命o行中的所有参敎ͼ但每一ơ运行还是会耗费一些时间。值得注意的是Q?
code_recognizer.py 它的(大的Q测试结果文件发送到
STDOUTQ而将一些友好的消息攑֜ STDERR
里。这样在大部分时间里Qؓ了安全保,您将会把 STDOUT
定向C个文Ӟq监视针对进E和l果概要?STDERR?/p>
清单 5Q运?
code_recognizer.py
> code2data.py py c java | code_recognizer.py > test_results.txt Total bytes of py-source: 457729 Total bytes of c-source: 245197 Total bytes of java-source: 709858 Input set: ) ( _ . = ; " , ' * / { } : - 0 + 1 [ ] HIDDEN = 8 LEARNRATE = 0.5 ITERATIONS = 1000 TRAINSIZE = 500 OUTPUTS = 3 MOMENTUM = 0.1 ERROR_CUTOFF = 0.01 TESTSIZE = 500 INPUTS = 20 error -> 95.519... 23.696... 19.727... 14.012... 11.058... 9.652... 8.858... 8.236... 7.637... 7.065... 6.398... 5.413... 4.508... 3.860... 3.523... 3.258... 3.026... 2.818... 2.631... 2.463... 2.313... 2.180... 2.065... 1.965... 1.877... 1.798... 1.725... [...] 0.113... 0.110... 0.108... 0.106... 0.104... 0.102... 0.100... 0.098... 0.096... 0.094... 0.093... 0.091... 0.089... 0.088... 0.086... 0.085... 0.084... Success rate against test data: 92.60%
不断减少误差是个很好的兆_q至在一D长旉里所获得的一U进步,且最后的l果必然是深入h心的。就我们的观点而言Q网l完成了一值得敬的工作,来识别代?
?我们会乐意們Q对于您的数字向量它是如何做的?
]]>开始写脚本引擎?/title> http://www.shnenglu.com/billhsu/archive/2008/07/28/57340.htmlBill Hsu Bill Hsu Mon, 28 Jul 2008 04:36:00 GMT http://www.shnenglu.com/billhsu/archive/2008/07/28/57340.html http://www.shnenglu.com/billhsu/comments/57340.html http://www.shnenglu.com/billhsu/archive/2008/07/28/57340.html#Feedback 5 http://www.shnenglu.com/billhsu/comments/commentRss/57340.html http://www.shnenglu.com/billhsu/services/trackbacks/57340.html 题记Q?br>
Python是荷Ch写的QRuby是日本h写的QLua是巴西h写的Q我q个中国人只能在q里脸红?br>
——CSDNȝ 孟岩
不打自讨没地写个要超qPython,Ruby,Lua的脚本引擎,以锻D力ؓ丅R?br>
估计完成以后和Lua有点像,宗旨是:以比Lua更短Q以比Python更长?/span> :-)
┏━┓ ┏━━┓ ┏┓
┃┃┣━┳━┫━━╋━┳┳╋╋━┳━━┓
┃ ┫━┃┃┣━━┃┣┫┏┫┃┃┣┓┏┛
┗┻┠Z┫┏┠Z━┻━┻┛┗┫┏┛┗┛
┗┛ ┗┛
引擎叫RapScript好了(R uby,Lua ,P ython 加一?
]]>
AVþþþòվ
|
ŷ鶹þþþþ |
Ʒһþþþþþվ |
þþAVɫۺ |
Ʒһþ㽶߿ۿ |
þþþŷղAV
|
Ļþ2017 |
þþƷһ |
þþƷ99Ʒ |
һþþƷ |
þˬˬAVƬ |
þþþþҹӰԺ |
þ99Ʒŷ |
ھƷþþþav |
þƵ |
Ʒþþ |
þþþùƷ۲ӰԺ |
94þùƷ
|
һձ˾þۺӰ |
99þó˹Ʒ |
þþþþþþþþþƷ |
99Ʒþþþþþ |
þþþƷһ |
þۺɫHEZYO |
þþƷһ
|
Ʒݾþþþ
|
þ99Ʒþþþþˮ |
þԭavapp |
ƷþëƬ |
þþWWW |
þˬˬƬAV |
þ99Ʒ99þ6 |
Ʒþþþþþþþþþ
|
Ʒһþ |
þ99Ʒһ |
AƷһþ |
99þùۺϾƷ鶹 |
þþþþ |
þùƷHDAV |
˾þþƷavһ |
˾þô߽av |