數(shù)學(xué)與算法-游戲編程_第1頁(yè)
數(shù)學(xué)與算法-游戲編程_第2頁(yè)
數(shù)學(xué)與算法-游戲編程_第3頁(yè)
數(shù)學(xué)與算法-游戲編程_第4頁(yè)
數(shù)學(xué)與算法-游戲編程_第5頁(yè)
免費(fèi)預(yù)覽已結(jié)束,剩余33頁(yè)可下載查看

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

向量幾何在游戲編程中的使用-TwinsenAndreLamothe說(shuō):“向量幾何是游戲程序員最好的朋友”。一點(diǎn)不假,向量幾何在游戲編程中的地位不容忽視,因?yàn)樵谟螒虺绦騿T的眼中,顯示屏幕就是一個(gè)坐標(biāo)系,運(yùn)動(dòng)物體的軌跡就是物體在這個(gè)坐標(biāo)系曲線運(yùn)動(dòng)結(jié)果,而描述這些曲線運(yùn)動(dòng)的,就是向量。使用向量可以很好的模擬物理現(xiàn)象以及基本的AI。<1>簡(jiǎn)單的2-DAndreLamothe程中的地位不容忽視,因?yàn)樵谟螒虺绦騿T的眼中,顯示屏幕就是一個(gè)坐標(biāo)系,運(yùn)動(dòng)物體的軌跡就是物體在這個(gè)坐標(biāo)系曲線運(yùn)動(dòng)結(jié)果,而描述這些曲線運(yùn)動(dòng)的,就是向量。使用向量可以很好的模擬物理現(xiàn)象以及基本的AI?,F(xiàn)在,先來(lái)點(diǎn)輕松的,復(fù)下中學(xué)知識(shí)向量v(用粗體字母表示向量)也叫矢量,是一個(gè)有大小有方向的量。長(zhǎng)度為1的向量稱為單位向量,也叫幺矢,這里記為E。長(zhǎng)度為0的向量叫做零向量,記為0,零向量沒(méi)有確定方向,換句話說(shuō),它的方向是任意的。一、向量的基1、向量加法:a+b等于使b的始點(diǎn)與a的終點(diǎn)重合時(shí),以a的始點(diǎn)為始點(diǎn),以b的終點(diǎn)為終點(diǎn)的向量。2、向量減法:-b等于使b的始點(diǎn)與a的始點(diǎn)重合時(shí),以b的終點(diǎn)為始點(diǎn),以a的終點(diǎn)為終點(diǎn)的向量。3 數(shù)量乘向量:k*a,k>0時(shí),等于a的長(zhǎng)度擴(kuò)大k倍;k=0時(shí),等于0向量;k<0時(shí),等a的長(zhǎng)度擴(kuò)大|k|倍然后反向它的幾何意義就是a的長(zhǎng)度與b在a上的投影長(zhǎng)度的乘積,或者是b的長(zhǎng)度與a在b上投影長(zhǎng)的乘積,它是一個(gè)標(biāo)量,而且可正可負(fù)。因此互相垂直的向量的內(nèi)積為05、向量的矢積(叉積):axb=|a|*|b|*sinA*v=c,|a|是a的長(zhǎng)度,|b|是b的長(zhǎng)度,A是a和b之間的銳夾角v是與ab所決定的平面垂直的幺矢,即axb與a、b都垂直。abc構(gòu)成右手系,即右手拇指伸直,其余四指按由a到b的銳角蜷曲,此時(shí)拇指所指方向就是c的方c。axb的行列式計(jì)算公式在左右手坐標(biāo)系下是不同的,如上圖所示。兩個(gè)向量的矢積是一6、正交向量的內(nèi)積:互相垂直的兩個(gè)向量是正交的,正交向量的內(nèi)積為零。 |a|.|b|*cos(PI/2)|a|.|b|*00二、向沒(méi)有下面的這些性質(zhì)做基礎(chǔ),我們后面向量技巧的推導(dǎo)將無(wú)法進(jìn)行。a+b=b+(a+b)+c=a+(b+a+0=0+a=a+(-a)=k*(l*a)=(k*l)*a=k*(a+b)=k*a+(k+l)*a=k*a+1*a=a.b=10)a.(b+c)=a.b+11)k*(a.b)=(k*a).b=12)0.a=13)a.a=三、自由向量的代數(shù)(分量)表1、向量在直角坐標(biāo)中的代數(shù)表a=(x,y)其中x,y分別是向量在x軸和y軸上的分量。任何一個(gè)在直角坐標(biāo)軸上的分量為(x,y)的向量都相等。比如上圖中的每個(gè)向量都表示為(-2,1)?;蛘邔?xiě)成a=x*i+y*j,即i和j的線性組合,這里i是x軸方向的單位向量(1,0),j是y軸方向的單位向量0,1),因此i正交于j。任意一個(gè)2-D向量都可以表成i與j的線性組合。|i|=|j|=2、向量的代數(shù)(分量)表示的向量加法分量表示:a+b=(xa,ya)+(x,yb)=(xa+x,ya+yb)向量減法分量表示:ab=(xa,ya)-(x,yb)=(xaxbyayb)向量的內(nèi)積(數(shù)量積、點(diǎn)積)分量表示=(xa*i+ya*j).(xb*i+yb*=xa*i*xb*i+xa*i*yb*j+ya*j*xb*i+ya*j*yb*=(xa*xb)*(i*i)+(xa*yb)*(i*j)+(xb*ya)*(i*j)+(ya*yb)*(j=xa*xb+ya*3、向量長(zhǎng)度(模)的計(jì)算以及單位化(歸一化設(shè)a=(x,y),則|a||(x,y)||x*iy*j|sqrt(x^2*i^2y^2*j^2 y^2),這里sqrt是開(kāi)平方a的單位向量為a/|a|,即(x,y)/sqrt(x^2y^2)?,F(xiàn)在,有了向量的基本知識(shí),我們就可以分析一個(gè)常見(jiàn)的問(wèn)題-屏幕上一點(diǎn)到另一點(diǎn)的追蹤,其實(shí)這一問(wèn)題也可理解為畫(huà)線問(wèn)題,畫(huà)線的算法有很多:DDA畫(huà)、中點(diǎn)畫(huà)以及高效的Bresenham算法。但這些算法一般只是畫(huà)一些兩端固定的線段時(shí)所使用的方法,再做一些動(dòng)態(tài)的點(diǎn)與點(diǎn)之間的時(shí)顯得不很靈活。使用向量的方法可以很好的解決此類問(wèn)題?,F(xiàn)在假設(shè)你正在編寫(xiě)一個(gè)飛行射擊游戲,你的敵人需要一種很厲害的-,這種在行進(jìn)的同時(shí)不斷的修正自己與目標(biāo)之間的位置關(guān)系,使得指向的方向總是玩家,而不論玩家的位置在哪里,這對(duì)一個(gè)水平不高的玩家(我?)來(lái)說(shuō)可能將是滅頂之災(zāi),玩家可能很詫異敵人會(huì)擁有這么先進(jìn)的,但對(duì)于你來(lái)說(shuō)只需要再程序循環(huán)中加入幾行代碼,它們的原理是向量的單位化和基本向量運(yùn)算首先我們要知道玩家的位置(x_playr,y_payer),然后,我們的就可以通過(guò)計(jì)算得到一個(gè)有初始方向的速度,速度的方向根據(jù)玩家的位置不斷修正,它的實(shí)質(zhì)是一個(gè)向量減法的計(jì)算過(guò)程。速度的大小我們自己來(lái)設(shè)置,它可快可慢,視游戲難易度而定,它的實(shí)質(zhì)就是向量單位化和數(shù)乘向量的過(guò)程。具體算法是:的更新速度(vx_mssile,vy_missie)=玩家的位置x_player,y_player)-的位置x_missie,y_missie),然后再對(duì)vx_missie,vy_mssil)做縮小處理,移動(dòng),判斷是否追到玩家,重新更新速度,縮小..看一下這個(gè)簡(jiǎn)單算法的代 假設(shè)x_player,y_player是玩家位置 x_missile,y_missile是位置分 xv_missile,yv_missile是的速度分floatn_missile;//這是玩家位置與位置之間向量的長(zhǎng)floatv_rate;//這是的速率縮放比 計(jì)算一下玩家與之間的位置向yv_missiley_player-y_missileyn_missile=sqrt(xv_missile*xv_missile+yv_missile*yv_missile)//歸一化的速度向量:xv_missilen_missileyv_missilen_missile 此時(shí)的速率為1,注意這里用速率//的速度分量滿足 好!現(xiàn)在的速度方向已經(jīng)被修正,它指向玩家 由于現(xiàn)在的速度太快,為了緩解一下緊張的氣氛,我要v_rate=0.2f;//比xv_missile*=v_rateyv_missile*=v_rate;//可以加速:v_rate大于1;v_rate大于0小于1,這里就這//行進(jìn)!的沖向玩家!x_missile+=xv_missile;y_missile+=yv_missile;//然后判斷是否成現(xiàn)在,你編寫(xiě)的敵人可以用玩家了。你也可以稍加修改,變?yōu)橹本€。這樣比較普遍?;镜男Ч孟蛄靠梢院芎玫哪M此時(shí),我們只用到了所述向量知識(shí)的很少的一部分。其他的知識(shí)會(huì)慢慢用到游戲中。這次先介紹到這里。下次我將說(shuō)說(shuō)利用向量模擬2-D物體任意角度返彈的技巧:)但是!別忘了復(fù)下向量的基礎(chǔ)知識(shí),我們要用到它們。<2>2-D物體任意角度的反第一次我說(shuō)了一下向量知識(shí)的基礎(chǔ)內(nèi)容和一點(diǎn)使用技巧,淺顯的展示了它在游戲編程中的作用。這次深入一些,充分利用向量的性質(zhì)模仿一個(gè)物理現(xiàn)象。首先,我要介紹一下將要使用的兩個(gè)基本但非常重要的技巧。一、求與某個(gè)向量a正交的向量ba.b==>xa*xb+ya*yb==>xa*xb=-=>xa/-ya=xbyaybxaxbyayb則向量(xa,ya)的正交向量為(xb,yb)=(-比如上圖中,向量(2,3)的逆時(shí)針旋轉(zhuǎn)90度的正交向量是(-3,2),順時(shí)針旋轉(zhuǎn)90度的正交向量為(3,-2)。這樣,任給一個(gè)非零向量(x,y),則它相對(duì)坐標(biāo)軸逆時(shí)針轉(zhuǎn)90度的正交向量為(-y,x),順時(shí)針90度的正交向量為(y,-x)二、計(jì)算一個(gè)向量b與另一向量a共線的兩個(gè)相反的投影我們看一下上面的圖,很明顯,cosA(A=X)關(guān)于y軸對(duì)稱,是偶函數(shù),因此cosAcos(-又因?yàn)閏osA是周期函數(shù),且周期是2*PI,則有cos(A+2*PIcosAcos(-Acos(-=a.b=|a|*|b|*cosA=|a|*|b|*cos(2*PI-現(xiàn)在,根據(jù)上圖,就有a.b|a|*|b|*cosA|a|*|b|*cos(2*PI-Aax*bx按照這個(gè)規(guī)則,當(dāng)上面的b與c的模相等時(shí),有|a|*|b||a|*|c|,進(jìn)一步的,當(dāng)它們與a的夾角A=B時(shí),就有a.b|a|*|b|*cosA|a|*|c|*cosBa.ca.b=|a|*|b|*cosA=|a|*|b|*cos(2*PI-A)=|a|*|c|*cosB=Ba.cax*bx+ay*by=ax*cx+我們還注意到在一個(gè)周期內(nèi),比如在[0,2*PI]中,cosA有正負(fù)兩種情況,分別是 2*PI)為正,在(PI/2,3/2*PI)為負(fù)。好,知道了這件事情之后,再 |a|*|b|*cosA,|a|和|b|都為正,所以a.b的正負(fù)性就由cosA決定,換句話說(shuō)a.b與它們夾角A的余弦cos當(dāng)A在(0,PI/2)&(3*PI/2,2*PI)中,此時(shí)2*PI-A在(-PI/2,0)&(0,PI/2)中,a.b當(dāng)A在 3*PI/2)中,此時(shí)2*PI-A也在 3*PI/2)中,a.b為現(xiàn)在我們?cè)賮?lái)看一下同模相反(夾角為PI)向量b和b與同一個(gè)向量a的兩個(gè)內(nèi)積之間有什么關(guān)系。首先BB2*PIPIPI,所以有b-b'b=-b(bx,by)=(-b'x,-b'y)=-(b'x,(b'x,b'y)=(-bx,-by)=-(bx,所a.b=(ax,ay).(bx,by)=(ax,ay).-(b'x,b'y)=a.-b'=-a.b'=(ax,ay).(b'x,b'y)=(ax,ay).-(bx,by)=a.-b=-好,有了上面的基礎(chǔ),我們就可以求一個(gè)向量b與另一向量a共線的兩個(gè)相反的投影向量cc'要求b在a上的投影向量c,我們可以用一個(gè)數(shù)乘上一個(gè)單位向量,這個(gè)單位向量要和a方向一至,我們記為a1。而這個(gè)數(shù)就是b在a上的投影長(zhǎng)。先來(lái)求單位向量a1,我們知道它就是向量a乘上它自身長(zhǎng)度的倒數(shù)(數(shù)乘向量),它的長(zhǎng)度我們可以求出,就是msqrt(ax^2ay^2),所以a1就是(ax/may/m),記為(a1x,再求投影長(zhǎng)/c/(注意//與||的區(qū)別,前者是投影長(zhǎng),可正可負(fù)也可為零,后者是實(shí)際的長(zhǎng)度,衡為非負(fù))。根據(jù)內(nèi)積的幾何意義:一個(gè)向量b點(diǎn)乘另一個(gè)向量a1,等于b在a1上投影長(zhǎng)與a1的長(zhǎng)的乘積。那我們要求b在a上的投影長(zhǎng),就用它點(diǎn)乘a的單位向量a1就可以了,因?yàn)閱挝幌蛄康拈L(zhǎng)度為1,b的投影長(zhǎng)/c/乘上1還等于投影長(zhǎng)自身,即:/c/=b.a1=(bx,by).(a1x,a1y)=bx*a1x+by*好,我們得到了c的投影長(zhǎng),現(xiàn)在就可以求出c=/c/*a1=((bx*a1x+by*a1y)*a1x,(bx*a1x+by*a1y)*a1y我們看到b與a1的夾角在(0,PI2)之間,因此它們的點(diǎn)積c/是個(gè)正值。因此當(dāng)它乘a1之后,得到向量的方向就是a1的方向?,F(xiàn)在來(lái)看b',它是b的同模相反向量,它和a1的夾角在(PI/2,3*PI/2)之間,因此b'點(diǎn)乘之后得到c'/是個(gè)負(fù)值,它再乘a1,得到向量的方向和a1相反。我們知道,一個(gè)向量b的同模相反向量b'與向量a的內(nèi)積ab',等于b與a的內(nèi)積的相反數(shù)-(.b)。因此,/c'/=-/c/,也就是說(shuō),它們的絕對(duì)值相等,符號(hào)相反。因此它們同乘一個(gè)a1,得到的的兩個(gè)模相等向量c與c'讓我們把它完成:(b'.a1)=-b'.a1b.a1)cb.a1)*a1c=-=>(b'.a1)*a1=-c=c=(b.a1)*a1=(-b'.a1)*c'=(b'.a1)*a1=(-b.a1)*至此為止,我們得出結(jié)論:當(dāng)一個(gè)向量b與另一個(gè)向量a的夾角在 之間,它在a方向上的投影向量c就是cba1*a1,其中a1是a的單位向量;它在相反的,也可以這樣說(shuō):當(dāng)一個(gè)向量b'與另一個(gè)向量a的夾角在(PI/2,3*PI/2)之間,它在a反方向上的投影向量c'cb'a1*a1a1是a的單位向量;它在a方向上的投影向量c是cba1)*a1。其中向量b是b'的同模相反向量。特別的,點(diǎn)乘兩個(gè)單位向量,得到它們夾角的余弦值E.E=|E|*|E|*cosA=1*1*cosA=好了,可完了。現(xiàn)在就可以看一下根據(jù)初等物理,相互接觸的物體在受到外力具有接觸面相對(duì)方向相對(duì)運(yùn)動(dòng)趨勢(shì)的時(shí)候,接觸面會(huì)發(fā)生形變從而產(chǎn)生相互作用的彈力。彈力使物體形變或形變同時(shí)運(yùn)動(dòng)形式發(fā)生改變。在知道了這件事情之后,我們開(kāi)始具體討論下面這種情況:矩形框和小球碰撞,碰撞時(shí)間極短,無(wú)限光滑從而碰撞過(guò)程沒(méi)有摩擦,碰撞時(shí)間極短,沒(méi)有能量損失..總之是一個(gè)理想的物理環(huán)境。我們?cè)谶@種理想環(huán)境下討論,小球與發(fā)生了完全彈性碰撞,且入射角和反射角相等:A=A',B=BC=C'..。虛線是法線,它和垂直。小球?qū)⒃诰匦慰蛑杏罒o(wú)休止的碰撞下去,且每次碰撞過(guò)程中入射角和反射角都相等。我們?cè)倬唧w點(diǎn),現(xiàn)在假設(shè)上面那個(gè)矩形墻壁的上下面平行于x軸,左右面平行于y軸。這樣太好了,我們?cè)诰帉?xiě)程序的時(shí)候只要判斷當(dāng)球碰到上下表面的時(shí)候?qū)方向速度值取返,碰到左右表面時(shí)將x方向速度值取返就行了,這種方法常常用在簡(jiǎn)單物理模型和規(guī)則邊界框的游戲編程上,這樣可以簡(jiǎn)化很多編程步驟,編寫(xiě)簡(jiǎn)單游戲時(shí)可以這樣處理??墒聦?shí)不總是像想向中的那么好。如果情況像下面這樣:雖然在碰撞過(guò)程中入射角仍然等于反射角,但是邊界的角度可沒(méi)那么“純”了,它們的角度是任意的,這樣就不能簡(jiǎn)單的將x方向或者y方向的速度取返了,我們要另找解決辦法。我們現(xiàn)在的任務(wù)是:已知物體的速度向量S和邊界向量b,求它的反射向量F。我們先來(lái)看一下在碰撞過(guò)程中都有哪些向量關(guān)系:設(shè)b是向量,S是入射速度向量,F(xiàn)是反射速度向量,也就是我們要計(jì)算的向量。A是入射角度,A'是反射角度,A=A'。N是b的法向量,即N垂直于b。n是與N共線的向量,'是N方向的單位向量。T是垂直于N的向量。根據(jù)向量加法,現(xiàn)在有關(guān)系:S+n=n+T=合并F=2*T-我們已經(jīng)找到了計(jì)算F的公式了。這里S是已知的,我們要計(jì)算一下T,看(1)T=S+要計(jì)算T,S是已知的,就要計(jì)算一下n。我們知道,n是S在N方向上投影得到的,S已知所以要得到n就要再計(jì)算一下N,而N又是和b垂直的。還記得剛才我們導(dǎo)出的使用向量的兩個(gè)技巧吧,這里我們都要用到:1、任給一個(gè)非零向量(x,y),則它相對(duì)坐標(biāo)軸逆時(shí)針轉(zhuǎn)90度的垂直向量為(-y,x),順時(shí)針轉(zhuǎn)度垂直向量為(y,-x)2、當(dāng)一個(gè)向量b與另一個(gè)向量a的夾角在(0,PI/2)&(3*PI/22*PI)之間,它在a方向上的投影向量c就是cb.a1*a1,其中a1是a的單位向量;它在a相反方向的投影向量c'是c'=(b'.a1)*a1,其中向量b'是b的同模相反向量。我們知道了b,用技巧1可以計(jì)算出N。然后歸一化N計(jì)算出n,再用技巧2,這里S和n'之間的夾角在PI2,3*PI2)中,因此要想用c=(b.1)*1,必須要使b=-,a1=n'。這樣就計(jì)算出了n。然后根據(jù)上面的(1)式計(jì)算出T,好了,有了T和F2*TS,你就擁有了計(jì)算出的F就是物體碰撞后的速度向量,在2-D中它有兩個(gè)分量x和y,3-D中有x,y,z三個(gè)分量。這里也證明了使用向量的一個(gè)好處就是在一些類似這樣關(guān)系推導(dǎo)過(guò)程中不用去考慮坐標(biāo)問(wèn)題,這里注意我們的向量b在實(shí)際的編程中是用的兩個(gè)端點(diǎn)坐標(biāo)相減計(jì)算出的,計(jì)算的時(shí)候不需要考慮相減的順序問(wèn)題。因?yàn)殡m然用不同的相減順序得到b的方向相反,且計(jì)算得到的單位法向量n'方向也相反(看上圖的虛線部分),但是當(dāng)用-S去點(diǎn)乘單位法向量'之后得到的值也是相反的,它有一個(gè)自動(dòng)的調(diào)節(jié)功能:現(xiàn)在假設(shè)以b為界,S一側(cè)為正方向。則如果單位法向量n'是正方向,與-S點(diǎn)積值也是正,正的'再乘正點(diǎn)積得正的n;如果單位法向量為負(fù)方向,與-S點(diǎn)積值也為負(fù)值,負(fù)的n'再乘負(fù)的點(diǎn)積得到的n為正方向??傊畁的方向是不變的,算出的F當(dāng)然也是不變的。四、編現(xiàn)在編碼實(shí)現(xiàn)它,但之前有一點(diǎn)說(shuō)一下,可能讀者已經(jīng)想到了,在反彈之前我們要先判斷什么時(shí)候開(kāi)始反彈,也就是什么時(shí)候碰撞,這是一個(gè)碰撞檢測(cè)問(wèn)題,本來(lái)這是我們應(yīng)該先要解決的問(wèn)題,但把它放到下一次在具體說(shuō),所以這里的編碼省略碰撞檢測(cè)的一步,直接計(jì)算反彈速度向量!目的是把上述理論迅速用到算法中去。 移動(dòng)的物體簡(jiǎn)化為質(zhì)點(diǎn),位置是//質(zhì)點(diǎn)速度向量的分量是 向量是bx=14.0f-6.0f=8.0f,by=4.0f-12.0f=- 則向量的垂直向量是Nx=-8.0f,Ny=-//這里可以加入 現(xiàn)在假設(shè)已經(jīng)碰撞完畢,開(kāi)始反floatlengthN=sqrt(Nx*Nx+Ny*Ny)歸一化N為floatn0xNxlengthNn0x就是n'的x分量floatn0yNylengthNn0y就是n'的y 計(jì)算n,就是S在N方向上的投影向根據(jù)b'b.a1').a1',有nfloatnxSvx*n0x+Svy*n0y)*n0xn的x分量floatnySvx*n0x+Svy*n0y)*n0yn的y計(jì)算//T=S+floatTxSvxnxT的x分量floatTySvynyT的y有了T,有了F2*TS計(jì)算floatFx2*TxSvxF的x分量floatFy2*TySvyF的y 現(xiàn)在已經(jīng)計(jì)算出了反彈后的速度向量Svx=Fx;Svy=Fy;x+=Svx;y+=Svy; 現(xiàn)在你就可以看到質(zhì)點(diǎn)被無(wú)情的反彈回去 而且是按照物理法則在理想環(huán)境下模就是這么簡(jiǎn)單,一個(gè)物理現(xiàn)象就可以模擬出來(lái),但是還不完善,只是針對(duì)直線,且沒(méi)有碰撞檢測(cè),下次分析一下后者,還是用向量的知識(shí)。這次先到這,Seeunexttime!<3>2-D邊界碰撞檢測(cè)-Twinsen-本人水平有限,疏忽錯(cuò)誤在所難免,還請(qǐng)各位數(shù)學(xué)高手、編程高手不吝賜教-我 -一、使用向量進(jìn)行檢測(cè)的原上次說(shuō)了使用向量模擬任意角度的反彈,這次談?wù)勊那疤?--碰撞在游戲中進(jìn)行碰撞檢測(cè),基本思路是這樣的:給定一個(gè)范圍,判斷物體在這次移動(dòng)后會(huì)不會(huì)進(jìn)入這個(gè)范圍,如果會(huì),就發(fā)生碰撞,否則不發(fā)生碰撞。在實(shí)際操作中,是用物體的邊界來(lái)判斷還是其他部位判斷完全取決于編程者。這時(shí)候,就可以從這個(gè)部位沿著速度的方向引出一條速度向量線,判斷一下這條線段(從檢測(cè)部位到速度向量終點(diǎn))和邊界線有沒(méi)有交點(diǎn),如果有,這個(gè)交點(diǎn)就是碰撞點(diǎn)。上面物體A,在通過(guò)速度向量移動(dòng)之后將到達(dá)B位置。但是,這次移動(dòng)將不會(huì)順利進(jìn)行,因?yàn)槲覀儼l(fā)現(xiàn),碰撞發(fā)生了。碰撞點(diǎn)就在那個(gè)紅域中,也就是速度向量和邊界線的交點(diǎn)。我們接下來(lái)的工作就是要計(jì)算這個(gè)交點(diǎn),這是一個(gè)解線性方程組的過(guò)程,那么要用到一樣工具二、一個(gè)解線性方程組的有力工具---克(Cramer)法首先要說(shuō)明一下的是,這個(gè)法則是有局限性的,它必須在一個(gè)線性方程組的系數(shù)行列式非零的時(shí)候才能夠使用。別緊張,我會(huì)好好談?wù)勊鼈兊?。首先讓我?lái)敘述一下這個(gè)法則(我會(huì)試著讓你感覺(jué)到這不是一堂數(shù)學(xué)課):如果線性方程組:A11*X1+A12*X2+...+A1n*Xn=b1A21*X1+A22*X2+...+A2n*Xn=An1*X1+An2*X2+...+Ann*Xn=A|A11A12...A1n|A21A22...A2n| |An1An2...Ann |A|線性方程組有解,且解是唯一的,并且解可以表X1d1/dX2d2/dXndn/d(這就是/A/=d為什么不能為零的原因這里d就是行列式/A/的值,dnn=1,2,3...)是用線性方程組的常數(shù)項(xiàng)b1,b2,...,bn替換系數(shù)矩陣中的第n列的值得到的矩陣的行列式的值,即:d1|b1A12...A1n|b2A22...A2n| |bnAn2...Annd2|A11b1...A1n|A21b2...A2n| |An1bn...Ann|A11A12...b1dn|A21A22...b2| |An1An2...bn別去點(diǎn)擊關(guān)閉窗口按鈕!我現(xiàn)在就舉個(gè)例子,由于我們現(xiàn)在暫時(shí)只討論2-D游戲(3-D以后會(huì)循序漸進(jìn)的談到),就來(lái)個(gè)2-D線性方程組:4.0*X1+2.0*X2=3.0*X1+3.0*X2=這里有兩個(gè)方程,兩個(gè)未知量,則根據(jù)上面的Cramer法則|4.02.0d|3.03.0|4.0*3.02.0*3.06.0(2階行列式的解法,'\'對(duì)角線相乘減去'/'對(duì)|5.02.0d1=|6.03.0|=5.0*3.0-2.0*6.0=|4.05.0d2=|3.06.0|=4.0*6.0-5.0*3.0=則X1=d1/d=3.0/6.0=0.5X2=d2/d=9.0/6.0=好了,現(xiàn)在就得到了方程組的唯一一組解。是不是已經(jīng)掌握了用Cramer法則解2-D線性方程組了?如果是的話,我們繼續(xù)。三、深入研究這里的2-D碰撞檢測(cè)的實(shí)質(zhì)就是判斷兩條線段是否有交點(diǎn),注意不是直線,是線段,兩直現(xiàn)在有v1和v2兩條線段,則根據(jù)向量v1e=v1b+s*v1v2e=v2b+那么我們要判斷v1和v2有沒(méi)有交點(diǎn),就讓v1e=v2e,看解出的s,t是不是在范圍內(nèi)就可以了:v1e==>v1b+s*v1=v2b+=>s*v1-t*v2=v2b-寫(xiě)成s*x_v1-t*x_v2=x_v2b-x_v1bs*y_v1-t*y_v2=y_v2b-現(xiàn)在是兩個(gè)方程式,兩個(gè)未知數(shù),則根據(jù)Cramer法則d|x_v1-x_v2|y_v1-y_v2=|4.0-2.0|1.0-3.0=-d1|x_v2b-x_v1b-x_v2|y_v2b-y_v1b-y_v2=|5.0-2.0|2.0-3.0=-s=d1/d=-11.0/-10.0=1.1>現(xiàn)在s已經(jīng)計(jì)算出來(lái),沒(méi)有在0.0,10]內(nèi),所以兩線段沒(méi)有交點(diǎn),從圖上看很直觀。t沒(méi)有必要再計(jì)算了。所以是物體與沒(méi)有發(fā)生碰撞。如果計(jì)算出的s,t都在[0.0,10]內(nèi),則把它們帶入原方程組,計(jì)算出v1e或者ve,它的分量就是碰撞點(diǎn)的分量。四、理論上的東西已經(jīng)夠多的了,開(kāi)始寫(xiě)程我現(xiàn)在要寫(xiě)一個(gè)用于處理碰撞檢測(cè)的函數(shù),為了測(cè)試它,我還準(zhǔn)備安排一些這是一個(gè)凸多邊形,我讓一個(gè)質(zhì)點(diǎn)在初始位置108),然后給它一個(gè)隨機(jī)速度,這個(gè)隨機(jī)速度的兩個(gè)分速度在區(qū)間1040]內(nèi),同時(shí)檢測(cè)是否與邊界發(fā)生碰撞。當(dāng)碰撞發(fā)生時(shí),就讓它回到初始位置,重新給一個(gè)隨機(jī)速度。//首先我要記下凸多邊形的邊界坐floatpoly[2][8]=6.0f2.0f4.0f8.0f14.0f18.0f14.0f6.0f所有點(diǎn)的x分量,最后一個(gè){2.0f6.0f10.0f14.0f12.0f8.0f4.0f2.0f所有點(diǎn)的y}floatx,yfloatvxvy//好,開(kāi)始編寫(xiě)碰撞floatstfloatx_v1,x_v2,y_v1,y_v2;floatx_v2b,x_v1b,y_v2b,y_v1b;forinti0i8-1+i//線x_v1=poly[0][i+1]-poly[0][i]y_v1=poly[1][i+1]-poly[1][i]x_v2=vx;y_v2=vy;//向量初始點(diǎn)x_v1bpoly[0][iy_v1bpoly[1][i//物置x_v2bxy_v2by計(jì)算d,d1和 |x_v1-x_v2//d=|y_v1-y_v2 |x_v2b-x_v1b-x_v2//d1=|y_v2b-y_v1b-y_v2 |x_v1x_v2b-x_v1b//d2=|y_v1y_v2b-y_v1bd=(x_v1*(-y_v2))-((-x_v2)*y_v1)d1=((x_v2b-x_v1b)*(-y_v2))-((-x_v2)*(y_v2b-y_v1b));d2=(x_v1*(y_v2b-y_v1b))-((x_v2b-x_v1b)*y_v1);ifabs(d0.001f如果等于零做近似處理,abs()d=0.001f計(jì)算參量s=d1/dt=d2/d//如果發(fā)生了就返回if(0.0f<=s&&1.0f>=s&&0.0f<=t&&1.0f>=t)returntrue;}//for(inti=0;i<8-1;++ireturnfalse;}//endofx=10.0f,y=8.0fvx=vy=(float)(rand()%4+1)//假設(shè)現(xiàn)在已經(jīng)在主循環(huán)中ifCollisionTestx=10.0f,y=8.0fvx=vy=(float)(rand()%4+1)}x+=vx;y+=vy;現(xiàn)在你就可以結(jié)合上次的討論模擬一個(gè)完整的理想物理情景:一個(gè)物體在不規(guī)則中移動(dòng)、反彈,永不停息...除非至此為止我們討論了2-D游戲的碰撞檢測(cè)以及它的編程實(shí)現(xiàn),在此過(guò)程中涉及到了線性數(shù)學(xué)的知識(shí),以后隨著深入還會(huì)不斷的加入的數(shù)學(xué)、物理知識(shí)<4>2-D物體間的這次我要分析兩個(gè)球體之間的碰撞響應(yīng),這樣我們就可以結(jié)合以前的知識(shí)來(lái)編寫(xiě)一款最基本2-D臺(tái)球游戲了,雖然粗糙了點(diǎn),但卻是個(gè)很好的開(kāi)始,對(duì)嗎?一、初步分析中學(xué)時(shí)候上物理課能夠認(rèn)真聽(tīng)講的人(我?哦,不包括我)應(yīng)該很熟悉的記得:當(dāng)兩個(gè)球體在一個(gè)理想環(huán)境下相撞之后,它們的總動(dòng)量保持不變,它們的總機(jī)械能也守恒。但這個(gè)理想環(huán)境是什么樣的呢?理想環(huán)境會(huì)不會(huì)影響游戲的真實(shí)性?對(duì)于前者我們做出在碰撞過(guò)程中理想環(huán)境的假設(shè):兩個(gè)球體相互作用的時(shí)間極短,且相互作用的內(nèi)力很大有了這樣的假設(shè),我們就可以使用動(dòng)量守恒和動(dòng)能守恒定律來(lái)處理它們之間的速度關(guān)系了,因?yàn)?)確保沒(méi)有外力參與,碰撞系統(tǒng)內(nèi)部動(dòng)量守恒,我們就可以使用動(dòng)量守恒定律。2)保證了我們的碰撞系統(tǒng)的總能量不會(huì)改變,我們就可以使用動(dòng)能守恒定律。3)兩球發(fā)生完全彈性碰撞,不會(huì)粘在一起,沒(méi)有動(dòng)量、能量損失。而對(duì)于剛才的第二個(gè)問(wèn)題,我的回答是不會(huì),經(jīng)驗(yàn)告訴我們,理想環(huán)境的模擬看起來(lái)也是很真實(shí)的。除非你是在進(jìn)行科學(xué)研究,否則完全可以這樣理想的去模擬?,F(xiàn)在,我們可以通過(guò)方程來(lái)觀察碰撞前后兩球的速度關(guān)系。當(dāng)兩球球心移動(dòng)方向共線(1-D處理)時(shí)的速度,或不共線2-D處理)時(shí)共線方向的速度分量滿足:m1*v1m2*v2m1*v1m2*v2(動(dòng)量守恒定律1/2*m1*v1^21/2*m2*v2^21/2*m1*v1'^21/2*m2*v2'^2(動(dòng)能守恒定律)這里m1和m2是兩球的質(zhì)量,是給定的,v1和v2是兩球的初速度也是我們已知的,v1'v2'是兩球的末速度,是我們要求的。好,現(xiàn)在我們要推導(dǎo)出v1'和v2'的表由(1),得到v1'(m1*v1m2*v2m2*v2')m1,代入(2)1/2*m1*v1^2+1/2*m2*v2^2=1/2*m1*(m1*v1+m2*v2-m2*v2')^2+1/2*m2*v2'^2v2(2*m2*v1v2*m1m2)m1m2)=>v1'=(2*m1*v2+v1*(m1-m2))/(m1+我們現(xiàn)在得到的公式可以用于處理當(dāng)兩球球心移動(dòng)方向共線1-D處理)時(shí)的速度關(guān)系,或者不共線2-D處理)時(shí)共線方向的速度分量的關(guān)系。不管是前者還是后者,我們都需要把它們的速度分解到同一個(gè)軸上才能應(yīng)用上述公式進(jìn)行處理。二、深入分首先我要說(shuō)明一件事情:當(dāng)兩球碰撞時(shí),它們的速度可以分解為球心連線方向的分速度和碰撞點(diǎn)切線方向的分速度。而由于它們之間相互作用的力只是在切點(diǎn)上,也就是球心連線方向上,因此我們只用處理這個(gè)方向上的力。而在切線方向上,它們不存在相互作用的力,而且在理想環(huán)境下也沒(méi)有外力,因此這個(gè)方向上的力在碰撞前后都不變,因此不處理。好,知道了這件事情之后,我們就知道該如何把兩球的速度分解到同一個(gè)軸上進(jìn)行處理。現(xiàn)在看上面的分析圖,s和t是我們根據(jù)兩個(gè)相碰球m1和m2的位置建立的輔助軸,我們一會(huì)就將把速度投影到它們上面。v1和v2分別是m1和m2的初速度,v1'和v'是它們碰撞后的末速度,也就是我們要求的。s'是兩球球心的位置向量,'是它的逆時(shí)針正交向量。s1是s'的單位向量,t1是t'的單位向量。我們的思路是這樣的:首先我們假設(shè)兩球已經(jīng)相碰(在程序中可以通過(guò)計(jì)算兩球球心之間的距離來(lái)判斷)。接下來(lái)我們計(jì)算一下'和t',注意'和t'的方向正反無(wú)所謂(一會(huì)將解釋),現(xiàn)在設(shè)m1球心為(m1x,m1y),m2球心為(m2x,m2y),則s'為(m1x-m2x,m1y-m2y),'為(m2y-m1y,m1x-m2x)(第一篇的知識(shí))。則sM=sqrt((m1x-m2x)^2+(m1y-m2y)^2),tMsqrt((m2y-m1y)^2+(m1x-m2x)^2),有s1=((m1x-m2x)/sM,(m1y-m2y)/sM)=(s1x,t1=((m2y-m1y)/tM,(m1x-m2x)/tM)=(t1x,現(xiàn)在s和t軸的單位向量已經(jīng)求出了,我們根據(jù)向量點(diǎn)乘的幾何意義,計(jì)算v1和v2在s1和t1方向上的投影值,然后將s軸上投影值代入公式來(lái)計(jì)算s方向碰撞后的速度。注意,根據(jù)剛才的說(shuō)明,t方向的速度不計(jì)算,因?yàn)闆](méi)有相互作用的力,因此,t方向的分速度不變。所以我們要做的就是:把v1投影到s和t方向上,再把v2投影到s和t方向上,用公式分別計(jì)算v1和v2在s方向上的投影的末速度,然后把得到的末速度在和原來(lái)v1和v2在t方向上的投影速度再合成,從而算出v1'和v'。好,我們接著這個(gè)思路做下去:先算v1(v1x,v1y)在s和t軸的投影值,分別設(shè)為v1s和v1t:v1s=v1.s1=>v1s=v1x*s1x+v1y*s1yv1t=v1.t1=>v1t=v1x*t1x+v1y*再算 v2y)在s和t軸的投影值,分別設(shè)為v2s和v2s==>v2s=v2x*s1x+v2y*s1yv2t=v2.t1=>v2t=v2x*t1x+v2y*接下來(lái)v1'(2*m1*v2v1*m1m2)m1m2)v2'(2*m2*v1v2*m1m2)m1m2)假設(shè)m1=m2=1v1s'=(2*1*v2s+v1s*(1-1))/(1+1)v2s'=(2*1*v1s+v2s*(1-1))/(1+=>v1s'==>v2s'=好,下一步,將v1s'和v1t再合成得到v1',將v2s'和v2t再合成得到v2,我們用向量和來(lái)做:首先求出v1t和v2t在t軸的向量v1t'和v2t'(將數(shù)值變?yōu)橄蛄縱1t'=v1t*t1=(v1t*t1x,v1t*v2t'=v2t*t1=(v2t*t1x,v2t*再求出v1s'和v2s'在s軸的向量v1s'和v2s'(將數(shù)值變?yōu)橄蛄縱1s'=v1s'*s1=(v1s'*s1x,v1s'*v2s'=v2s'*s1=(v2s'*s2x,v2s'*最后v1'=v1t'+v1s'=(v1t*t1x+v1s'*s1x,v1t*t1y+v1s'*v2'=v2t'+v2s'=(v2t*t1x+v2s'*s2x,v2t*t1y+v2s'*從而就求出了v1'和v'。下面解釋為什么說(shuō)s'和t'的方向正反無(wú)所謂:不論我們?cè)谟?jì)算s'時(shí)使用m1的球心坐標(biāo)減去m2的球心坐標(biāo)還是相反的相減順序,由于兩球的初速度的向量必有一個(gè)和s1是夾角大于90度小于270度的,而另外一個(gè)與s1的夾角在0度和90度之間或者說(shuō)在270度到360度之間,則根據(jù)向量點(diǎn)積的定義|a|*|b|*cosA,計(jì)算的到的兩個(gè)投影值一個(gè)為負(fù)另一個(gè)為正,也就是說(shuō),速度方向相反,這樣就可以用上面的公式區(qū)求得末速度了。同時(shí),求出的末速度也是方向相反的,從而在轉(zhuǎn)換為vs'和vs'時(shí)也是正確的方向。同樣的,求'既可以是用'逆時(shí)針90度得到也可以是順時(shí)針90度得到。三、編寫(xiě)代碼按照慣例,該編寫(xiě)代碼了,其實(shí)編寫(xiě)的代碼和上面的推導(dǎo)過(guò)程極為相似。但為了完整,我還是打算寫(xiě)出來(lái)。 用于球體碰撞響應(yīng)的函數(shù),其中v1a和v2a為兩球的初速度向量 v1f和v2f是兩球的末速度向量//m1和m2是兩球的位置向s'的分量為(sx,sy),t'的分量為(tx,voidBall_Collision(v1a,v2a,&v1f,&v2f,m1,求出doublesx=m1.x-m2.xdoublesy=m1.y-m2.y求出doubles1x=sx/sqrt(sx*sx+sy*sy);doubles1y=sy/sqrt(sx*sx+sy*sy)求出doubletx=-sy;doublety=sx;求出doublet1x=tx/sqrt(tx*tx+ty*ty);doublet1y=ty/sqrt(tx*tx+ty*ty)//求v1a在s1上的投影doublev1s=v1a.x*s1x+v1a.y*s1y//求v1a在t1上的投影doublev1t=v1a.x*t1x+v1a.y*t1y//求v2a在s1上的投影doublev2s=v2a.x*s1x+v2a.y*s1y//求v2a在t1上的投影doublev2t=v2a.x*t1x+v2a.y*t1ydoublev1sf=v2s;doublev2sf=v1s; 最后一步,注意這里我們簡(jiǎn)化一下,直接將v1sf,v1t和v2sf,v2t投影到x,y軸上v1'和v2'在x,y軸上的分doublensxv1sf*s1xdoublensyv1sf*s1ydoublentx=v1t*t1x;doublenty=v1t*t1y;投影到x軸和y x軸單位向量為(1,0),y軸為//v1f.x=1.0*(nsx*1.0+nsy*0.0)//v1f.y=1.0*(nsx*0.0+nsy*1.0)//v1f.x+=1.0*(ntx*1.0+nty*0.0)//v1f.y+=1.0*(ntx*0.0+nty*1.0)v1f.x=nsx+ntx;v1f.y=nsy+nty//然后將v2sf和v2tnsx=v2sf*s1x;nsy=v2sf*s1y;ntx=v2t*t1x;nty=v2t*t1y;投影到x軸和y x軸單位向量為(1,0),y軸為//v2f.x=1.0*(nsx*1.0+nsy*0.0)//v2f.y=1.0*(nsx*0.0+nsy*1.0)//v2f.x+=1.0*(ntx*1.0+nty*0.0)//v2f.y+=1.0*(ntx*0.0+nty*1.0);v2f.x=nsx+ntx;v2f.y=nsy+nty}//endof呼~(yú)~是不是感覺(jué)有點(diǎn)亂阿?不管怎么樣,我有這種感覺(jué)。但我們確實(shí)完成了它。希望你能夠理解這個(gè)計(jì)算的過(guò)程,你完全可以依照這個(gè)過(guò)程自己編寫(xiě)更高效的代碼,讓它看上去更清楚:)至此位置,我們已經(jīng)掌握了編寫(xiě)一個(gè)臺(tái)球游戲的基本知識(shí)了 事實(shí)上,一切才剛剛起步,我們還有很多沒(méi)有解決的問(wèn)題,比如旋轉(zhuǎn)問(wèn)題,擊球的角度問(wèn)題等等,你還會(huì)深入的研究一下,對(duì)嗎?一旦你有了目標(biāo),堅(jiān)持下去,保持,總會(huì)有成功的一天:)這次就到這里,下次我們接著研究,Byefornow~~<5>對(duì)于游戲程序員來(lái)說(shuō),有了向量的旋轉(zhuǎn),就代表有了游戲中物體旋轉(zhuǎn)的,而不論它是一個(gè)平面精靈還是一組空間的網(wǎng)格體亦或是我們放在3-D世界某一點(diǎn)的相機(jī)。我們?nèi)孕杞柚蛄縼?lái)完成我們此次的旅程,但這還不夠,我們還需要一個(gè)朋友,就是矩陣,一個(gè)我們用來(lái)對(duì)向量進(jìn)行線性變換的GooLuY。就像我們剛剛提及向量時(shí)所做的一樣,我們來(lái)復(fù)下即將用到的數(shù)學(xué)知識(shí)。(這部分知識(shí)我只會(huì)一帶而過(guò),因?yàn)槲覍阎攸c(diǎn)放在后面對(duì)旋轉(zhuǎn)問(wèn)題的分析上一、矩陣的基對(duì)于3x3矩陣(也叫3x3方陣,行列數(shù)相等的矩陣也叫方陣)m和Mm+(-)M=[ab [AB [a+(-)Ab+(-)Bc+(-[def]+(-)[DEF]=[d+(-)De+(-)Ef+(-[gh [GH [g+(-)Gh+(-)Hi+(-性質(zhì)1)m(MNmM)+2)mMMkxM=[ABC] [kxAkxBkxC]kx[DEF]=[kxDkxEkxF][GH [kxGkxH性質(zhì)k和l(k+l)xM=kxM+lxkx(m+M)=kxm+kxkx(lxM)=(kxl)x1xM=kx(mxMkxmxMmx(kxM)mxM[ab [AB [def]x[DEF]=[dxA+exD+fxGdxB+exE+fxHdxC+exF+fxI][ghi] [GHI] [gxA+hxD+ixGgxB+hxE+ixHgxC+hxF+ixI]可以看出,矩陣相乘可以進(jìn)行的條件是第一個(gè)矩陣的列數(shù)等于第二個(gè)矩陣的行數(shù)。由矩陣乘法的定義看出,矩陣乘法不滿換率,即在一般情況下,mxM!=Mxm。(mxMxNmx(Mx乘法加法分配律mx(MNmxMmxN(mMxNmxNMx4、矩m'[ab [ad[def]=[be[gh [cfi性質(zhì)1)(mxM)'=M'x2)(m')'=3)(m+M)'=m'+4)(kxMkxM'[10E010稱為3[00性質(zhì):對(duì)于任意3級(jí)矩陣M,有ExMMMxE6、矩如果3x3級(jí)方陣m,有mxM=Mxm=E,這里E是3級(jí)單位陣,則可以說(shuō)m是可逆的,它的逆矩陣為M,也記為m^-1。相反的,也可以說(shuō)M是可逆的,逆矩陣為m,也記為M^-1。性質(zhì):(m^-1)^-1=(kxm)^-1=1/kxm^-13)(m')^-1=(m^-1)'4)(mxM)^-1=M^-1xn^-矩陣求逆有幾種算法,這里不深入研究,當(dāng)我們用到的時(shí)候在討論在我們建立了矩陣的概念之后,就可以用它來(lái)做坐標(biāo)的線性變換。好,現(xiàn)在我們開(kāi)始來(lái)使用它。二、基礎(chǔ)的2-D繞原點(diǎn)旋轉(zhuǎn)首先是簡(jiǎn)單的2-D向量的旋轉(zhuǎn),以它為基礎(chǔ),我們會(huì)深入到復(fù)雜的3-D旋轉(zhuǎn),最后使我們可以在3-D中無(wú)所不能的任意旋轉(zhuǎn)。在2-D的迪坐標(biāo)系中,一個(gè)位置向量的旋轉(zhuǎn)公式可以由三角函數(shù)的幾何意義推出。比如圖所示是位置向量R逆時(shí)針旋轉(zhuǎn)角度B前后的情況。在左圖中,我們有關(guān)系x0=|R|*cosAy0=|R|*cosA=x0/|R|sinA=y0/x1|R|*cos(A+B)y1|R|*x1|R|*(cosAcosBsinAsinB)y1|R|*(sinAcosBcosAsinB)cosA=x0/|R|sinA=y0/代入上面的式子,得x1=|R|*(x0*cosB/|R|-y0*sinB/|R|)y1=|R|*(y0*cosB/|R|+x0*sinB/x1=x0*cosB-y0*sinBy1=x0*sinB+y0*這樣我們就得到了2-D迪坐標(biāo)下向量圍繞圓點(diǎn)的逆時(shí)針旋轉(zhuǎn)公式。順時(shí)針旋轉(zhuǎn)就把角度變?yōu)樨?fù):x1=x0*cos(-B)-y0*sin(-B)y1=x0*sin(-B)+y0*cos(-x1=x0*cosB+y0*sinBy1=-x0*sinB+y0*cosB現(xiàn)在我要把這個(gè)旋轉(zhuǎn)公式寫(xiě)成矩陣的形式,有一個(gè)概念我簡(jiǎn)單提一下,平面或空間里的每個(gè)線性變換(這里就是旋轉(zhuǎn)變換)都對(duì)應(yīng)一個(gè)矩陣,叫做變換矩陣。對(duì)一個(gè)點(diǎn)實(shí)施線性變換就是通過(guò)乘上該線性變換的矩陣完成的。好了,打住,不然就跑題了。所以2-D旋轉(zhuǎn)變換矩陣就是[cosAsinA] [cosA-sinA][-sinAcosA[sinAcosA]我們對(duì)點(diǎn)進(jìn)行旋轉(zhuǎn)變換可以通過(guò)矩陣完成,比如我要點(diǎn)(x,y)繞原點(diǎn)逆時(shí)針旋轉(zhuǎn):[cosAsinA][x,y]x[-sinAcosA]=[x*cosA-y*sinA為了編程方便,我們把它寫(xiě)成兩[x,y] [cosAsinA] [x*cosA-y*sinAx*sinA+y*cosA][0,0]x[-sinAcosA]=[0 也可以[cosA-sinA] [x0] [x*cosA-y*sinA0][sinAcosA]x[y0]=[x*sinA+y*cosA0]三、2-D的繞任一點(diǎn)旋下面我們深入一些,思考另一種情況:求一個(gè)點(diǎn)圍繞任一個(gè)非原點(diǎn)的中心點(diǎn)旋轉(zhuǎn)。我們剛剛導(dǎo)出的公式是圍繞原點(diǎn)旋轉(zhuǎn)的公式,所以我們要想繼續(xù)使用它,就要把想要圍繞的那個(gè)非原點(diǎn)的中心點(diǎn)移動(dòng)到原點(diǎn)上來(lái)。按照這個(gè)思路,我們先將該中心點(diǎn)通過(guò)一個(gè)位移向量移動(dòng)到原點(diǎn),而圍繞點(diǎn)要保持與中心點(diǎn)相對(duì)位置不變,也相應(yīng)的按照這個(gè)位移向量位移,此時(shí)由于中心點(diǎn)已經(jīng)移動(dòng)到了圓點(diǎn),就可以讓同樣位移后的圍繞點(diǎn)使用上面的公式來(lái)計(jì)算旋轉(zhuǎn)后的位置了,計(jì)算完后,再讓計(jì)算出的點(diǎn)按剛才的位移向量逆位移,就得到圍繞點(diǎn)繞中心點(diǎn)旋轉(zhuǎn)一定角度后的新位置了。看下面的圖現(xiàn)在求左下方的藍(lán)色點(diǎn)圍繞紅色點(diǎn)旋轉(zhuǎn)一定角度后的新位置。由于紅色點(diǎn)不在原點(diǎn),所以可以通過(guò)紅色向量把它移動(dòng)到原點(diǎn),此時(shí)藍(lán)色的點(diǎn)也按照這個(gè)向量移動(dòng),可見(jiàn),紅色和藍(lán)色點(diǎn)的相對(duì)位置沒(méi)有變?,F(xiàn)在紅色點(diǎn)在原點(diǎn),藍(lán)色點(diǎn)可以用上面旋轉(zhuǎn)變換矩陣進(jìn)行旋轉(zhuǎn),旋轉(zhuǎn)后的點(diǎn)在通過(guò)紅色向量的的逆向量回到它實(shí)際圍繞下方紅色點(diǎn)旋轉(zhuǎn)后的位置。在這個(gè)過(guò)程中,我們對(duì)圍繞點(diǎn)進(jìn)行了三次線性變換:位移變換-旋轉(zhuǎn)變換-位移變換,我們把它寫(xiě)成矩陣形式:[xy [cosAsinA [x'y'-[010]x 0]x[-sinAcosA0]x 0]=[---[00 [rtxrty [-rtx-rty [---最后得到的矩陣的x'和y'就是我們旋轉(zhuǎn)后的點(diǎn)坐標(biāo)注意到矩陣乘法滿足結(jié)合律:(mxMxNmxMxN),我們可以先將所有的變換矩陣 [cosAsinA M= 0]x[-sinAcosA0]x [rtxrty [-rtx-rty然后再[xy[010]x[00像這樣歸并變換矩陣是矩陣運(yùn)算一個(gè)常用的方法,因?yàn)楫?dāng)把諸多變換矩陣歸并為一個(gè)矩陣之后,對(duì)某點(diǎn)或向量的重復(fù)變換只需要乘一個(gè)矩陣就可以完成,減少了計(jì)算的開(kāi)銷。本小節(jié)討論的這種“其他變換-繞點(diǎn)旋轉(zhuǎn)變換-的旋轉(zhuǎn)變換不可能一步完成,必須使用這種旁敲側(cè)擊、化繁為簡(jiǎn)的方法,尤其是在3-D空間中,可能需要在真正做規(guī)定度數(shù)的旋轉(zhuǎn)前還要做一些其他必要旋轉(zhuǎn)變換,也就是要做很多次的旋轉(zhuǎn),但總體的思想還是為了把復(fù)雜的問(wèn)題分成若干簡(jiǎn)單的問(wèn)題去解決,而每一個(gè)簡(jiǎn)單問(wèn)題都需要一WeGo!四、基礎(chǔ)的3-D繞坐標(biāo)軸方向旋就像2D繞原點(diǎn)旋轉(zhuǎn)一樣,3-D的繞坐標(biāo)軸旋轉(zhuǎn)是3-D旋轉(zhuǎn)的基礎(chǔ),因?yàn)槠渌麖?fù)雜的3-D旋轉(zhuǎn)最后都會(huì)化簡(jiǎn)為繞坐標(biāo)軸旋轉(zhuǎn)。其實(shí),剛才我們推導(dǎo)出的在xoy坐標(biāo)面繞o旋轉(zhuǎn)的公式可以很容易的推廣到3-D空間中,因?yàn)樵?-D直角坐標(biāo)系中,三個(gè)坐標(biāo)軸兩兩正交,所以z軸垂直于xoy面,這樣,在xoy面繞o點(diǎn)旋轉(zhuǎn)實(shí)際上在3-D空間中就是圍繞z軸旋轉(zhuǎn),如下圖左所示:這描述了左手系中某點(diǎn)在xoy、yoz、xoz面上圍繞原點(diǎn)旋轉(zhuǎn)的情況,同時(shí)也是分別圍繞z、x、y坐標(biāo)軸旋轉(zhuǎn)??梢?jiàn)在3-D空間中繞坐標(biāo)軸旋轉(zhuǎn)相當(dāng)于在相應(yīng)的2-D平面中圍繞原點(diǎn)旋轉(zhuǎn)。我們用矩陣來(lái)說(shuō)明:設(shè)p(xyz)是3-D空間中的一點(diǎn),也可以說(shuō)是一個(gè)位置向量,當(dāng)以上圖中的坐標(biāo)為準(zhǔn),p點(diǎn)p繞z軸逆時(shí)針和順時(shí)針旋轉(zhuǎn)角度A[xyz [cosA-sinA0 [xyz [cosAsinA0[0100]xsinAcosA00][0100]xsinAcosA0[001 01[001 01[000 00[000 00p繞x軸逆時(shí)針和順時(shí)針旋轉(zhuǎn)角度A[xyz [1 [xyz [1 [0100]x[0cossinA0[0100]x[0cosAsinA[001 [0sincosA [001 [0-sinAcosA[000 [0 [000 [0 p繞y軸逆時(shí)針和順時(shí)針旋轉(zhuǎn)角度A[xyz [cosA0sinA [xyz [cosA0-sinA[0100]x 0]和[0100]x 1 [001 [-sinA0cosA [001 [sinA0cosA[000 [000 0 以后我們會(huì)把它們寫(xiě)成這樣的標(biāo)準(zhǔn)4x4方陣形式,Why?為了便于做平移變換,還記得上小節(jié)做平移時(shí)我們把2x2方陣寫(xiě)為3x3方陣嗎?讓我們繼續(xù)研究。我們?cè)侔呀Y(jié)論推廣一點(diǎn),讓它適用于所有和坐標(biāo)軸平行的軸,具體一點(diǎn),讓它適用于所有和y軸平行的軸。這個(gè)我們很快可以想到,可以按照2-D的方法“平移變換-旋轉(zhuǎn)變換-平移變換”來(lái)做到,看下圖要實(shí)現(xiàn)point繞axis旋轉(zhuǎn),我們把a(bǔ)xis按照一個(gè)位移向量移動(dòng)到和y換為axis',為了保持point和axis的相對(duì)位置不變,pont也通過(guò)相同的位移向量做相應(yīng)的位移。好,現(xiàn)在移動(dòng)后的point就可以用上面的旋轉(zhuǎn)矩陣圍繞axis'也就是y軸旋轉(zhuǎn)了,旋轉(zhuǎn)后用相反的位移向量位移到實(shí)際圍繞axis假設(shè)axis為xs,zt,要point(x,yz)圍繞它逆時(shí)針旋轉(zhuǎn)度數(shù)A,按照“平移變換-旋轉(zhuǎn)[xyz [100 [cosA0sinA [100 [x'yz'-[010 [010 1 [010 [0010]x[0010]x[-sinA0cosA0]x[0010]= [000 [-s0-t 0 [s0t 則得到的(xy,z')就是point圍繞axis旋轉(zhuǎn)角A后的位置。[xyz [100 [100 [xy'z'-[010 [010 [0cosA-sinA [010 [0010]x[0010]x[0sinAcosA0]x[0010]= [000 [0-s-t [0st 平行于z軸且圍繞軸x=s,y=t逆時(shí)針旋轉(zhuǎn)角A的變[xyz 00 [cosA-sinA0 [100 [x'y'z-[010 10 [sinAcosA0 [010 [0010]x010]x 0]x[0010]= [000 [-s-t0 [st0 逆時(shí)針旋轉(zhuǎn)就把上面推出的相應(yīng)逆時(shí)針旋轉(zhuǎn)變換矩陣帶入即可。至此我們已經(jīng)討論了3-D空間基本旋轉(zhuǎn)的全部,接下來(lái)的一小節(jié)是我們3-D旋轉(zhuǎn)部分的重頭戲,也是3-D能最強(qiáng)大的轉(zhuǎn)變換。五、3-D繞任意Wow!終于來(lái)到了最后一部分,這一節(jié)綜合運(yùn)用上面涉及到的所有旋轉(zhuǎn)知識(shí),完成空間一點(diǎn)或著說(shuō)位置向量圍繞空間任意方向旋轉(zhuǎn)軸的旋轉(zhuǎn)變換(我在下面介紹的法是一個(gè)稍微繁瑣一點(diǎn)的方法,大體上看是利用幾個(gè)基本旋轉(zhuǎn)的綜合。我將在下一篇中介紹一個(gè)高檔一些的方法)。何謂任意方向的旋轉(zhuǎn)軸呢?其實(shí)就是空間一條直線。在空間解析幾何中,決定空間直線位置的兩個(gè)值是直線上一點(diǎn)以及直線的方向向量。在旋轉(zhuǎn)中,我們把這個(gè)直線稱為一個(gè)旋轉(zhuǎn)軸,因此,直線的這個(gè)方向向量我們叫它軸向量,它類似于3-D動(dòng)畫(huà)中四元數(shù)的軸向量。我們?cè)趯?shí)際我們先討論旋轉(zhuǎn)軸通過(guò)原點(diǎn)的情況。目前為止對(duì)于3-D空間中的旋轉(zhuǎn),我們可以做的只標(biāo)軸方向的旋轉(zhuǎn)。因此,當(dāng)我們考慮非坐標(biāo)軸方向旋轉(zhuǎn)的時(shí)候,很自然的想到,可以將這個(gè)旋轉(zhuǎn)軸通過(guò)變換與某一個(gè)坐標(biāo)軸重合,同時(shí),為了保持旋轉(zhuǎn)點(diǎn)和這個(gè)旋轉(zhuǎn)軸相對(duì)位置不變,旋轉(zhuǎn)點(diǎn)也做相應(yīng)的變換,然后,讓旋轉(zhuǎn)點(diǎn)圍繞相應(yīng)旋轉(zhuǎn)軸重合的坐標(biāo)軸旋轉(zhuǎn),最后將旋轉(zhuǎn)后的點(diǎn)以及旋轉(zhuǎn)軸逆變換回原來(lái)的位置,此時(shí)就完成了一點(diǎn)圍繞這個(gè)非坐標(biāo)軸方向旋轉(zhuǎn)軸的旋轉(zhuǎn)。我們?cè)賮?lái)看圖分析。圖中有一個(gè)紅色的分量為x0,y0,z0)的軸向量,此外有一個(gè)藍(lán)色位置向量圍繞它旋轉(zhuǎn),由于這個(gè)軸向量沒(méi)有與任何一個(gè)坐標(biāo)軸平行,我們沒(méi)有辦法使用上面推導(dǎo)出的旋轉(zhuǎn)變換矩陣,因此必須將該軸變換到一個(gè)坐標(biāo)軸上,這里我們選擇了z軸。在變換紅色軸的同時(shí),為了保持藍(lán)色位置向量同該軸的相對(duì)位置不變,也做相應(yīng)的變換,然后就出現(xiàn)中圖描述的情況。接著我們就用可以用變換矩陣來(lái)圍繞z軸旋轉(zhuǎn)藍(lán)色向量相應(yīng)的度數(shù)。旋轉(zhuǎn)完畢后,再用剛才變換的逆變換把兩個(gè)向量相對(duì)位置不變地還原到初始位置,此時(shí)就完成了一個(gè)點(diǎn)圍繞任意過(guò)原點(diǎn)的軸的旋轉(zhuǎn),對(duì)于不過(guò)原點(diǎn)的軸我們?nèi)匀挥谩拔灰谱儞Q-旋轉(zhuǎn)變換-位移變換”的方法,一會(huì)討論。在理解了基本思路之后,我們來(lái)研究一下變換吧!我們就按上圖將紅色軸變到z軸上,開(kāi)始吧!首先我們假設(shè)紅軸向量是一個(gè)單位向量,因?yàn)檫@樣在一會(huì)求sin和cos時(shí)可以簡(jiǎn)化計(jì)算,在實(shí)際編程時(shí)可以先將軸向量標(biāo)準(zhǔn)化。然后我準(zhǔn)備分兩步把紅色軸變換到z軸上去:1)將紅色軸變換到y(tǒng)oz 將yoz平面上的紅色軸變到z軸至于這兩個(gè)變換的方法...我實(shí)在沒(méi)有別的辦法了,只能夠旋轉(zhuǎn)了,你覺(jué)得呢?先把它旋轉(zhuǎn)到y(tǒng)oz平面上我們?cè)O(shè)軸向量旋轉(zhuǎn)到y(tǒng)oz面的變換為(繞z軸旋轉(zhuǎn)[cosA0[-sinA0 1 0接著我們要求出cosA和snA,由上圖,沿著z軸方向看去,我們看到旋轉(zhuǎn)軸向量到y(tǒng)oz面在xoy面就是將軸的投影向量旋轉(zhuǎn)角度A到y(tǒng)軸上,現(xiàn)在我不知道角度A,但是我們可以利用它直接求出cosA和sinA,因?yàn)槲覀冎狸P(guān)系:cosAy0軸向量在xoysinAx0軸向量在xoy我們?cè)O(shè)軸向量的投影長(zhǎng)為lrsqrt(x0^2y0^2),呵呵,現(xiàn)在,我們第一步的變換矩陣就[y0/lrx0/lr0[-x0/lry0/lr00100同時(shí)我們得到逆變換矩陣[y0/lr-x0/lr0[x0/lry0/lr00100然后我們進(jìn)行第二步:將yoz平面上的紅色軸變到z軸上。我們的變換矩陣是(繞x軸旋轉(zhuǎn)[1 [0cosBsinB[0-sinBcosB[0 由圖,這是經(jīng)第一次旋轉(zhuǎn)后的軸向量在yoz面中的情形,此次我們要求出上面變換中的cosB和sinB,我們?nèi)圆恢澜嵌菳,但我們還是可以利用它求cosB和snB。由于第一次旋轉(zhuǎn)是圍繞z軸,所以軸向量的z分量沒(méi)有變,還是0。此外,軸向量現(xiàn)在的y分量和原來(lái)不同了,我們?cè)倏匆幌碌谝淮巫儞Q那,可以發(fā)現(xiàn)軸向量在旋轉(zhuǎn)到y(tǒng)oz面后,y分量變成了剛才軸向量在xoy面上的投影長(zhǎng)lr了。Ys!是時(shí)候?qū)懗鯿osB和sinB了:cosBz0sinBlr還記得我們剛才假設(shè)軸向量是一個(gè)單位向量嗎?所以cosB=z0sinB=lr至此我們的第二個(gè)變換就[1 [0z0[0-lr[0 相應(yīng)逆變換矩陣[1 [0z0-lr[0lrz0[0 現(xiàn)在總結(jié)一下,我們對(duì)于空間任意點(diǎn)圍繞某個(gè)任意方向且過(guò)原點(diǎn)的軸旋轉(zhuǎn)的變換矩陣就是:[y0/lrx0/lr0 [1 0 [cosAsinA0 [10 [y0/lr-00

[-x0/lry0/lr0 [0z0lr [-sinAcosA0 [0z0-lr [x0/lrM= 10]x[0-lrz00]x 10]x[0lrz00]x 0 [0 0 0 [00 0上面的變換是“旋轉(zhuǎn)變換-旋轉(zhuǎn)變換-旋轉(zhuǎn)變換-旋轉(zhuǎn)變換-旋轉(zhuǎn)變換”的變換組。當(dāng)我們需要讓空間中的某個(gè)位置向量圍繞一個(gè)軸旋轉(zhuǎn)角度A的時(shí)候,就可以用這個(gè)向量相應(yīng)的矩陣乘上這個(gè)M,比如[xy0 [x'y'z'-[010 [0010]xM= [000 當(dāng)然,M中矩陣相應(yīng)的元素是根據(jù)軸向量得到的以上的變換矩陣是通過(guò)把軸向量變到z軸上得到的,而且是先旋轉(zhuǎn)到y(tǒng)oz面上,然后再旋轉(zhuǎn)到z軸上。我們也可以不這樣做,而是先把軸向量旋轉(zhuǎn)到xoz面上,然后再旋轉(zhuǎn)到z軸上。此外,我們還可以把軸向量變到x或y軸上,這一點(diǎn)我們可以自己決定。雖然變換不同,但推導(dǎo)的道理是相同的,都是這種“其他變換-實(shí)際旋轉(zhuǎn)變換-其他變換”的滲透形式。剛才分析的是旋轉(zhuǎn)軸過(guò)原點(diǎn)的情況,對(duì)于一般的旋轉(zhuǎn)軸,雖然我們也都是把它的軸向量放到原點(diǎn)來(lái)考慮,但我們不能只是讓旋轉(zhuǎn)點(diǎn)圍繞過(guò)原點(diǎn)的軸向量旋轉(zhuǎn)完就算完事,我們?nèi)孕枰捎谩捌揭谱儞Q-旋轉(zhuǎn)變換-平移變換”方法。即先將旋轉(zhuǎn)軸平移到過(guò)原點(diǎn)方向,旋轉(zhuǎn)點(diǎn)也做相應(yīng)平移,接著按上面推出的變換陣旋轉(zhuǎn),最后將旋轉(zhuǎn)軸和點(diǎn)逆平移回去。這里,我們只需在M的左右兩邊各加上一個(gè)平移變換即可。這個(gè)平移變換的元素是根據(jù)軸向量與原點(diǎn)之間的距離向量得到的,比如旋轉(zhuǎn)軸與原點(diǎn)的距離向量是(x,y,l),則我們的變換就變成00[1010[00m=010]Mx01[-lx-ly-lz [lxlylz變換矩陣m就是全部7個(gè)變換矩陣的歸并,適用于各種旋轉(zhuǎn)情況我們現(xiàn)在已經(jīng)討論完了一般的2-D、3-D旋轉(zhuǎn)了??梢钥闯銎浠镜乃枷脒€是能夠化繁為簡(jiǎn)的變換、歸并。而實(shí)際的旋轉(zhuǎn)也仍是用我們最最基本的2-D繞原點(diǎn)旋轉(zhuǎn)公式。其實(shí)還有很多的旋轉(zhuǎn)效果可以用我們上面的變換、公式稍加修改獲得。比如螺旋形旋轉(zhuǎn)、旋轉(zhuǎn)加前進(jìn)、隨機(jī)旋轉(zhuǎn)等等。下一篇將介紹一個(gè)用的最多的高檔一些的方法,下次見(jiàn)。在3-D空間中,我們用空間坐標(biāo)系來(lái)規(guī)范物體的位置,空間坐標(biāo)系由3個(gè)相互垂直的坐標(biāo)軸組成,我們就把它們作為我們觀察3-D空間的基礎(chǔ),空間中物體的位置可以通過(guò)它們來(lái)衡量。當(dāng)我們把這3個(gè)坐標(biāo)軸上單位長(zhǎng)度的向量記為3個(gè)相互正交的單位向量ijk,空間中每一個(gè)點(diǎn)的位置都可以被這3個(gè)向量線性表出,如P<12,3>這個(gè)點(diǎn)可以表為i-2j+3k。我們把這3個(gè)正交的單位向量稱為空間坐標(biāo)系的基,它們單位長(zhǎng)度為1且正交,所以可以成標(biāo)準(zhǔn)正交基。三個(gè)向量叫做基向量?,F(xiàn)在我們用矩陣形式寫(xiě)出基向量和基。i=|100j=|010k=|001|i| |100|B=|j|=|010|k |001這樣的矩陣我們叫它基矩陣。有了基矩陣,我們就可以把空間坐標(biāo)系中的一個(gè)向量寫(xiě)成坐標(biāo)乘上基矩陣的形式,比如上面的向量P可以寫(xiě)成:P=Cx|1-23||1-23||100|010|001這樣的話,空間坐標(biāo)系下的同一個(gè)向量在不同的基下的坐標(biāo)是不同的。二、局部坐標(biāo)系和局部坐標(biāo)和空間坐標(biāo)系(也可以叫做全局坐標(biāo)系或者世界坐標(biāo)系)并存的稱為局部坐標(biāo)系(也叫坐架—— frame),它有自己的基,這些基向量把空間坐標(biāo)系作為參考系。比| |-1 0B'=|y'|=| 0| | -1|x''| |2^?/2 2^?/2 B''=|y''|=|0 | |-(2^?) 2^?/2就是兩個(gè)局部坐標(biāo)系的基,如圖現(xiàn)在我們可以把上面那個(gè)空間坐標(biāo)中的向量 - 3|(以后都用矩陣表示)表示在不同的下,我把它寫(xiě)成一個(gè)大長(zhǎng)串的式子:|x' |P=|Px'Py'Pz'|x|y'|=|Px''Py''Pz''|x||z' |這里|PxPy'Pz'|是P在B'下的坐標(biāo),|Px''PyPz''|是P在B''下的坐標(biāo),我把它寫(xiě)的具體點(diǎn)|1-23|=|-1-2-3||-100|010|00-1=|2^?||2^?02^? |-(2^?)02^?這就是說(shuō),在空間坐標(biāo)系下面的向量|1-23|在基B'下的坐標(biāo)為|-1-2-3|,在B''下的坐標(biāo)為|2*2^?-22^?|。當(dāng)然空間坐標(biāo)系也有自己的基B|ijk|^T(因?yàn)槭橇邢蛄?,所以在研究了局部坐?biāo)系之后,我現(xiàn)在要分析兩個(gè)應(yīng)用它們的例子,先來(lái)看三、空間坐標(biāo)系中一個(gè)點(diǎn)圍繞任一軸的旋轉(zhuǎn)上一篇討論3-D空間旋轉(zhuǎn)的時(shí)候說(shuō)到有一個(gè)高檔的方法做3-D空間任意軸旋轉(zhuǎn),現(xiàn)在我們的知識(shí)儲(chǔ)備已經(jīng)足夠理解這個(gè)方法了(Quake引擎使用的就是這個(gè)方法)。如上所示,空間坐標(biāo)系中的一個(gè)局部坐標(biāo)系xyz中有一個(gè)向量(253)和一個(gè)點(diǎn)p8,4,2)現(xiàn)在我要讓p點(diǎn)圍繞a向量旋轉(zhuǎn)60度,得到p’點(diǎn),該如何做呢?從目前掌握的旋轉(zhuǎn)知識(shí)來(lái)看,我們有兩個(gè)理論基礎(chǔ):在一個(gè)坐標(biāo)系中的一個(gè)點(diǎn),如果要它圍繞該坐標(biāo)系中一個(gè)坐標(biāo)軸旋轉(zhuǎn),就給它的坐標(biāo)值乘相應(yīng)的旋轉(zhuǎn)矩陣,如[cosA-sinA0][sinAcosA0][001]等等我們已經(jīng)學(xué)習(xí)了局部坐標(biāo)系的理論了,知道空間中一個(gè)點(diǎn)在不同的坐標(biāo)系中的坐標(biāo)不同。利用這一點(diǎn),我們可以很方便的讓一個(gè)點(diǎn)或者向量在不同的坐標(biāo)系之間轉(zhuǎn)換。我們聯(lián)系這兩個(gè)理論根據(jù),得出我們的思路1構(gòu)造另一個(gè)局部坐標(biāo)系abc,使得a成為該坐標(biāo)系的一個(gè)坐標(biāo)軸 把p的坐標(biāo)變換到abc中,得到p’,用旋轉(zhuǎn)公式讓p’圍繞已經(jīng)成為坐標(biāo)軸的ap’’3把p’’再變換回坐標(biāo)系xyz,得到p’’’,則p’’’就是p圍繞a旋轉(zhuǎn)后的點(diǎn)。下面我們逐步說(shuō)明。首先我們構(gòu)造abc,我們有無(wú)數(shù)種方法構(gòu)造,因?yàn)橹灰WCb、c之間以及他們和a之間都正交就可以了,但我們只要一個(gè)。根據(jù)上圖,我們首先產(chǎn)生一個(gè)和a正交的b。這可以通過(guò)向量的叉乘來(lái)完成:我們?nèi)×硪粋€(gè)向量v(顯然,這個(gè)向量是不能和a共線的任何非零向量),讓它和a決定一個(gè)平面x,然后讓v叉乘a得到一個(gè)垂直于x的向量b,因?yàn)閎垂直于x,而a在平面x上,因此b一定垂直于a,然后用a叉乘b得到c,最后單位化a、b、c,這樣就得到了局部坐標(biāo)系ac。然后我們把p點(diǎn)變換到abc坐標(biāo)系中,得到p’,即p’就是p在abc中的坐標(biāo):|abc|*p’=|xyz|*p’=|abc|^-1*|xyz|*|axbxcx||100|p’=|aybycy|^-1*|010|*|azbzcz||001|注意這里|abc|^-1即矩陣|abc|的逆矩陣,因?yàn)閍、b、c是三個(gè)正交向量,并且是單位向量,因此|abc|是一個(gè)正交矩陣,正交矩陣的轉(zhuǎn)置和逆相等,這是它的一個(gè)特性,因此上面|axayaz||100|p’=|bxbybz|*|010|*|cxcycz|

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論