導航:首頁 > 源碼編譯 > 三維旋轉演算法

三維旋轉演算法

發布時間:2022-08-11 04:24:14

㈠ 關於三維動畫軟體maya的旋轉問題

經過二個小時的研究,我知道這是什麼問題和解決問題的辦法,首先在maya里旋轉物體之後會導致兩個軸並成一個軸,用gimbal(萬向結)模式可以看出來,導致少了一個軸,然而你還要去旋轉那個軸就沒得轉,這時你只能用world或local的方式去旋轉,看上去是旋轉了其實已經亂了,因為maya計算旋轉的方式是gimbal的方式,然後我查了一下網上好多網友都表示魔方的綁定是很難的,需要編程了,然後我想到一個不用編程的辦法,雖然麻煩但還是能做出來,首先復制好28個魔小塊,軸心可以不改,然後用約束的方式來直接生成動畫,用的是父子約束,建一個約束物體,比如圓圈或別的什麼,把要轉的一排約束給圓圈,圓圈K幀,整排小塊跟著轉,先整排小塊之後打開曲線編輯器,bakechannel得到小塊的曲線,然後解除約束,後面依此類推,就可以完全做出來了

㈡ 已知三維空間三個點A,B,C坐標確定的一個平面,求此平面分別繞X軸,Y軸,Z軸旋轉的角度為多少

這個問題應該是高中立體幾何的內容,我現在已經放下10多年了。具體的演算法忘記了,不過可以給你提供個思路。有了三個點的坐標,這個平面N方程就可以確定,X、Y、Z軸的方程也可以寫出來,那麼就可以求出X軸與平面N 的交角,我覺得你說的這個旋轉角度應該就是這個交角。

㈢ 請教個三維坐標系換算的演算法

設(x1,y1)投影到三維坐標中變為(x2,y2,z2),則x2=x1,y2=y1,z2=ax1+by1+c
x和y的坐標不會變的,因為「x軸投影到三維坐標系的xy面與其x軸重合」

㈣ ICP演算法的介紹

三維空間R3存在兩組含有n個坐標點的點集,分別為: PL和PR。三維空間點集PL中各點經過三維空間變換後與點集PR中點一一對應,其單點變換關系式為:(0-1)上式中,R為三維旋轉矩陣,t為平移向量。在ICP配准方法中,空間變換參數向量X可表示為[9] 。參數向量中四元數參數滿足約束條件為:(0-2)根據迭代的初值X0,由式(0-1)計算新點集Pi為:(0-3)式中,P表示原始未修改過的點集,Pi的下標i表示迭代次數,參數向量X的初始值X0為 。根據以上數據處理方法,ICP配准演算法可以概括為以下七個步驟:1) 根據點集Plk中的點坐標,在曲面S上搜索相應就近點點集Prk;2) 計算兩個點集的重心位置坐標,並進行點集中心化生成新的點集;3) 由新的點集計算正定矩陣N,並計算N的最大特徵值及其最大特徵向量;4) 由於最大特徵向量等價於殘差平方和最小時的旋轉四元數,將四元數轉換為旋轉矩陣R;5) 在旋轉矩陣R被確定後,由平移向量t僅僅是兩個點集的重心差異,可以通過兩個坐標系中的重心點和旋轉矩陣確定;6) 根據式(0-3),由點集Plk計算旋轉後的點集P』lk。通過Plk與P』lk計算距離平方和值為fk+1。以連續兩次距離平方和之差絕對值 作為迭代判斷數值;7) 當 時,ICP配准演算法就停止迭代,否則重復1至6步,直到滿足條件 後停止迭代

㈤ CAD三維建模旋轉不能查詢體積

體積要用用查詢工具查詢。
查詢工具在面板上位於「默認」->「實用工具」中:體積演算法,測量封閉對象的面積,注意可以通過加/減選項來對面積進行計算。

㈥ 兩個三維空間內相互垂直的向量旋轉的問題

首先,如果再讓a以b(注意這里是b,不是b')為軸旋轉β°,得到a',a『和b'不一定相互垂直。

例如: a(1,0,0), b(0,1,0), 向量b以a為軸旋轉90°, 再讓a以b為軸旋轉90°,則a『和b'都與(0,0,1)共線。於是 a『和b'不垂直。

設 a=(x1,y1,z1), b=(x2,y2,z2), 不妨假設a,b都為單位向量。設 c=a×b=(y1z2-y2z1, z1x2-z2x1,x1y2-x2y1), 於是 a,b,c為兩兩相互垂直的單位向量。
設旋轉變換為T, 則T由下列方程組決定:
Ta=a
Tb=cosα b + sinα c
Tc= -sinα b + cosα c
T(a,b,c)=(a,b,c)(1,0,0;0,cosα, -sinα; 0,sinα, cosα )^T=(a,b,c)M,
其中 M=(1,0,0;0,cosα, -sinα; 0,sinα, cosα )。
設 e1=(1,0,0), e2=(0,1,0), e3=(0,0,1)
則 (a,b,c)^T=(x1,y1,z1; x2,y2,z2; x3,y3,z3)(e1,e1,e3)^T=A(e1,e1,e3)^T
其中 計c=(x3,y3,z3), 設A=(x1,y1,z1; x2,y2,z2; x3,y3,z3),因為(e1,e1,e3) 和(a,b,c)為兩組單位正交基,所以A*A^T=單位矩陣。
於是 (e1,e2,e3)=(a,b,c)A
於是 任給一點 X=(x,y,z)=xe1+ye2+ze3,
TX=T(xe1+ye2+ze3)=xTe1+yTe2+zTe3=T(e1,e2,e3)*(x,y,z)^T=T(a,b,c)A(x,y,z)^T=
=(a,b,c)MA(x,y,z)^T=(e1,e2,e3)A^TMA(x,y,z)^T
所以,旋轉的變換矩陣為: A^TMA

㈦ 旋轉matlab三維散點圖

%%最後加一句

view([-6015])

㈧ 什麼是marching cubes演算法具體怎麼講的

Marching Cubes演算法(醫學圖像三維繪制中的面繪制)2007-08-16 00:50建議要看的資料
[1] Lorensen W E, Cline H E .Marching cubes: a high-resoulution 3D suface construction algorithm [J], Computer Graphics,1987, 21(4):163~169
[2]集成化醫學影像演算法平台理論與實踐田捷,趙明昌,何暉光 清華大學出版社2004年10月
[3]Polygonising a scalar field Also known as: "3D Contouring", "Marching Cubes", "Surface Reconstruction"
http://local.wasp.uwa.e.au/~pbourke/geometry/polygonise/Marching Cubes;
[4]www.3dmed.net

Marching Cubes演算法工作原理
Marching Cubes演算法是三維數據場等值面生成的經典演算法,是體素單元內等值面抽取技術的代表。
等值面是空間中所有具有某個相同值的點的集合。它可以表示為, ,c是常數。則稱F(f)為體數據f中的等值面。
在MC演算法中,假定原始數據是離散的三維空間規則數據場。用於醫療診斷的斷層掃描(CT)及核磁共振成像(MRI) 等產生的圖像均屬於這一類型。MC演算法的基本思想是逐個處理數據場中的體素,分類出與等值面相交的體素,採用插值計算出等值面與體素棱邊的交點。根據體素中每一頂點與等值面的相對位置,將等值面與立方體邊的交點按一定方式連接生成等值面,作為等值面在該立方體內的一個逼近表示。在計算出關於體數據場內等值面的有關參數後山常用的圖形軟體包或硬體提供的面繪制功能繪制出等值面。

圖2.1 離散的三維空間規則數據場中的一個體素
2.1.1 MC演算法的主要步驟
1. 確定包含等值面的體素
離散的三維空間規則數據場中的一個體素可以用圖2.1表示。8個數據點分別位於該體素的8個角點上。MC演算法的基本假設是:沿著體素的邊其數據場呈局部連續線性變化,根據這個假設,可認為,如果兩個相鄰采樣點一個為正點,一個為負點,則它們連成的邊上一定存在且僅有一個等值點 (設等值面值為c)。如果得到了體素各條邊上的等值點,就可以以這些點為頂點,用一系列的三角形擬合出該體素中的等值面。因此確定立方體體素中等值面的分布是該演算法的基礎。
首先對體素的8個頂點進行分類,以判斷其頂點是位於等值面之外,還是位於等值面之內。再根據8個頂點的狀態,確定等值面的剖分模式。頂點分類規則為:
1. 如體素頂點的數據值大於或等於等值面的值,則定義該頂點位於等值面之外, 記為正點,即「1「
2. 如體素頂點的數據值小於等值面的值,則定義該頂點位於等值面之內,記為負點, 即「0"
由於每個體素共有8個頂點,且每個頂點有正負兩種狀態,所以等值面可能以 =256種方式與一個體素相交。通過列舉出這256種情況,就能創建一張表格,利用它可以查出任意體素中的等值面的三角面片表示。如果考慮互補對稱性,將等值面的值和8個角點的函數值的大小關系顛倒過來,即將體素的頂點標記置反(0變為1, 1變為0),這樣做不會影響該體素的8個角點和等值面之間的拓撲結構,可將256種方式簡化成128種。其次,再利用旋轉對稱性,可將這128種構型進一步簡化成15種。圖3.2給出了這15種基本構型[131其中黑點標記為「1」的角點。

圖2.2 分布狀態表

圖2.3 體素角點分布不同情況
基於上面的分析,MC演算法中用一個位元組的空間構造了一個體素狀態表,如圖2.2所示,該狀態表中的每一位可表示出該體元中的一個角點的0或1的狀態。根據這一狀態表,就可知道當前體素屬於圖2.3中哪一種情況,以及等值面將與哪一條邊相交。
2.求等值面與體元邊界的交點
在確定體素內三角剖分模式後,就要計算三角片頂點位置。當三維離散數據場的密度較高時,即當體素很小時,可以假定函數值沿體素邊界呈線性變化,這就是MC演算法的基本假設。因此,根據這一基本假設,可以直接用線性插值計算等值面與體素邊的交點。
對於當前被處理體素的某一條邊,如果其兩頂點 , 的標記值不同,那麼等值面一定與此邊相交,且僅有一個交點。交點為 其中P代表等值點坐標, , 代表兩個端點的坐標, , 代表兩個端點的灰度值,v代表域值。求出等值面與體素棱邊的交點以後,就可以將這些交點連接成三角形或多邊形,形成等值面的一部分。
3.等值面的法向量計算
為了利用圖形硬體顯示等值面圖象,必須給出形成等值面的各三角面片的法向分量,選擇適當的局部面光照模型進行光照計算,以生成真實感圖形。
對於等值面上的每一點,其沿面的切線方向的梯度分量應該是零,因此,該點的梯度矢量的方向也就代表了等值面在該點的法向量,當梯度值非零。所幸的是等值面往往是由兩種具有不同密度的物質的分解面,因此其上的每點的梯度矢量均不為零,即
Mc演算法採用中心差分方法求采樣點p〔m ,n, k ) 處的梯度矢量,公式如下:

Gx=〔g(i+1,j,k)-g(i-1,j,k)〕/2dx
Gy=〔g(i,j+1,k)-g(i,j-1,k)〕/2dy
Gz=〔g(i,j,k+1)-g(i,j,k-1)〕/2dz
其中D(i,j ,k)是切片k在像素(i,j)的密度, , , 是立方體邊的長度。對g進行歸一化,得到(gx/|g|,gy/|g|,gz/|g|)作為(i,j,k)上的單位法向量。然後,對體素八個頂點上法向量進行線性插值就可得到位於體素棱邊上的三角片的各個頂點上的法向量。設計算得到的某個三角片的三個頂點上的單位法向量分別為( , 和 ),這個三角片的幾何重心為 ,則該三角片的法向量起始於 ,終止於 。代入Gourand光照模型公式,就可計算出小三角片表面的光強(灰度)。將其投影在某個特定的二維平面上進行顯示,從而顯示出物體富有光感的整個表面形態。其中我們在內存中保留四個切片來計算立方體中所有頂點梯度。
2.1.2 MC演算法流程
1、將三維離散規則數據場分層讀入內存;
2、掃描兩層數據,逐個構造體素,每個體素中的8個角點取自相鄰的兩層;
3、將體素每個角點的函數值與給定的等值面值c做比較,根據比較結果,構造
該體素的狀態表;
4、根據狀態表,得出將與等值面有交點的邊界體素;
5、通過線性插值方法計算出體素棱邊與等值面的交點;
6、利用中心差分方法,求出體素各角點處的法向量,再通過線性插值方法,求出三角面片各頂點處的法向;
7,根據各三角面片上各頂點的坐標及法向量繪制等值面圖像。
========================================================
MC代碼
MarchingCubes(float lowThreshold,float highThreshold,float XSpace,float YSpace,float ZSpace)
{
//記錄生成的頂點數和面數初始時應該為0
m_vNumber=0;
m_fNumber=0;
//當前Cube中生成的頂點和面數
int vertPos,facePos;
//包圍盒的尺寸 用於繪製程序計算整個場景的包圍盒,用於調整觀察位置,以使整個場景盡可能占滿整個窗口。
float min[3],max[3];
min[0]=min[1]=min[2]=max[0]=max[1]=max[2]=0;//初始化
//當前掃描層的切片數據和一個臨時的切片數據
short *pSliceA,*pSliceB,*pSliceC,*pSliceD,*tempSlice;

pSliceA=pSliceB=pSliceC=tempSlice=NULL;
int imageWidth,imageHeight,imageSize,sliceNumber;
imageWidth=imageHeight=512;//我們是512×512的數據
imageSize=imageWidth*imageHeight;
sliceNumber=m_FileCount-1;
if((highThreshold*lowThreshold)==0)
{
return 0;
}
pSliceD =new short [imageSize];
//因為等值面是每相鄰兩層切片為單位進行提取的,所以在處理後兩層切片時難免生成前兩層切片已經生成的頂點,這時候就用下面的數組記錄哪些邊上的頂點已經生成了,如果遇到已經生成的頂點就不再重復計算而是直接使用記錄的索引,否則就生成新的頂點。
long *bottomXEdge=new long[imageSize];
long *bottomYEdge=new long[imageSize];
long *topXEdge=new long[imageSize];
long *topYEdge=new long[imageSize];
long *zEdge=new long[imageSize];

tempSlice=new short [imageSize];

if(bottomXEdge==NULL||bottomYEdge==NULL||
topXEdge==NULL||topYEdge==NULL||
zEdge==NULL||tempSlice==NULL)
{
return 0;//錯誤
}
//初始化數據
memset(bottomXEdge,-1,sizeof(long)*imageSize);
memset(bottomYEdge,-1,sizeof(long)*imageSize);
memset(topXEdge,-1,sizeof(long)*imageSize);
memset(topYEdge,-1,sizeof(long)*imageSize);
memset(zEdge,-1,sizeof(long)*imageSize);
memset(tempSlice,0,sizeof(short)*imageSize);

//計算某一層頂點和三角時所需要的一些變數
//一些循環變數
int i,j,k,w,r;
//cube類型
unsigned char cubeType(0);
//計演算法向量
float dx[8],dy[8],dz[8],squaroot;
//記錄某個Cube生成
float vertPoint[12][6];
int cellVerts[12]; //what use
int triIndex[5][3]; //每個cube最多生成5條邊

//用於記錄已生成頂點索引的臨時變數
int offset;
//當前cube8個頂點的灰度值
short cubegrid[8];
long *edgeGroup;
//得到數據

pSliceD=m_volumeData;
pSliceB=tempSlice;
pSliceA=tempSlice;

int tt,tt1;

//掃描4層切片的順序
/*
-----------------------D |
-----------------------B |
-----------------------C |
-----------------------A |
V
*/
//marching cubes 演算法開始實行 ?第一次循環時,只讀入一個切片?
for(i=0;i<=(sliceNumber);i++)
{
pSliceC=pSliceA;
pSliceA=pSliceB;
pSliceB=pSliceD;
if(i>=sliceNumber-2)
{
pSliceD=tempSlice;
}
else
{

pSliceD+=imageSize;
}
for(j=0;j<imageHeight-1;++j)
for(k=0;k<imageWidth-1;++k)
/* for(j=10;j<imageHeight-5;j++)//調試用
for(k=10;k<imageWidth-5;k++)*/
{
//得到八個頂點的灰度值step0
cubegrid[0]=pSliceA[j*imageWidth+k];
cubegrid[1]=pSliceA[j*imageWidth+k+1];
cubegrid[2]=pSliceA[(j+1)*imageWidth+k+1];
cubegrid[3]=pSliceA[(j+1)*imageWidth+k];
cubegrid[4]=pSliceB[j*imageWidth+k];
cubegrid[5]=pSliceB[j*imageWidth+k+1];
cubegrid[6]=pSliceB[(j+1)*imageWidth+k+1];
cubegrid[7]=pSliceB[(j+1)*imageWidth+k];
//計算cube的類型
cubeType=0;
for(w=0;w<8;w++)
{

if((cubegrid[w]>lowThreshold)&&(cubegrid[w]<highThreshold))//需要畫的點

{
cubeType|=(1<<w);
}
}//end for計算cube的類型
if(cubeType==0||cubeType==255)
{
continue;
}
for(w=0;w<12;w++) //初始化cellVerts表到零
{
cellVerts[w]=-1;
}
//計算6個方向相鄰點的象素差值(用於計演算法向量)
if(k==0)
{
dx[0]=pSliceA[j*imageWidth+1];
dx[3]=pSliceA[(j+1)*imageWidth+1];
dx[4]=pSliceB[j*imageWidth+1];
dx[7]=pSliceB[(j+1)*imageWidth+1];
}
else
{
dx[0]=pSliceA[j*imageWidth+k+1]
-pSliceA[j*imageWidth+k-1];
dx[3]=pSliceA[(j+1)*imageWidth+k+1]
-pSliceA[(j+1)*imageWidth+k-1];
dx[4]=pSliceB[j*imageWidth+k+1]
-pSliceB[j*imageWidth+k-1];
dx[7]=pSliceB[(j+1)*imageWidth+k+1]
-pSliceB[(j+1)*imageWidth+k-1];
}
if(k==imageWidth-2)
{
dx[1]=-pSliceA[j*imageWidth+imageWidth-2];
dx[2]=-pSliceA[(j+1)*imageWidth+imageWidth-2];
dx[5]=-pSliceB[j*imageWidth+imageWidth-2];
dx[6]=-pSliceB[(j+1)*imageWidth+imageWidth-2];
}
else
{
dx[1]=pSliceA[j*imageWidth+k+2]
-pSliceA[j*imageWidth+k];
dx[2]=pSliceA[(j+1)*imageWidth+k+2]
-pSliceA[(j+1)*imageWidth+k];
dx[5]=pSliceB[j*imageWidth+k+2]
-pSliceB[j*imageWidth+k];
dx[6]=pSliceB[(j+1)*imageWidth+k+2]
-pSliceB[(j+1)*imageWidth+k];
}
if(j==0)
{
dy[0]=pSliceA[imageWidth+k];
dy[1]=pSliceA[imageWidth+k+1];
dy[4]=pSliceB[imageWidth+k];
dy[5]=pSliceB[imageWidth+k+1];
}
else
{
dy[0]=pSliceA[(j+1)*imageWidth+k]
-pSliceA[(j-1)*imageWidth+k];
dy[1]=pSliceA[(j+1)*imageWidth+k+1]
-pSliceA[(j-1)*imageWidth+k+1];
dy[4]=pSliceB[(j+1)*imageWidth+k]
-pSliceB[(j-1)*imageWidth+k];
dy[5]=pSliceB[(j+1)*imageWidth+k+1]
-pSliceB[(j-1)*imageWidth+k+1];
}
if(j==imageHeight-2)
{
dy[2]=-pSliceA[(imageHeight-2)*imageWidth+k+1];
dy[3]=-pSliceA[(imageHeight-2)*imageWidth+k];
dy[6]=-pSliceB[(imageHeight-2)*imageWidth+k+1];
dy[7]=-pSliceB[(imageHeight-2)*imageWidth+k];
}
else
{
dy[2]=pSliceA[(j+2)*imageWidth+k+1]-pSliceA[j*imageWidth+k+1];
dy[3]=pSliceA[(j+2)*imageWidth+k]-pSliceA[j*imageWidth+k];
dy[6]=pSliceB[(j+2)*imageWidth+k+1]-pSliceB[j*imageWidth+k+1];
dy[7]=pSliceB[(j+2)*imageWidth+k]-pSliceB[j*imageWidth+k];
}
dz[0]=pSliceB[j*imageWidth+k]
-pSliceC[j*imageWidth+k];
dz[1]=pSliceB[j*imageWidth+k+1]
-pSliceC[j*imageWidth+k+1];
dz[2]=pSliceB[(j+1)*imageWidth+k+1]
-pSliceC[(j+1)*imageWidth+k+1];
dz[3]=pSliceB[(j+1)*imageWidth+k]
-pSliceC[(j+1)*imageWidth+k];
dz[4]=pSliceD[j*imageWidth+k]
-pSliceA[j*imageWidth+k];
dz[5]=pSliceD[j*imageWidth+k+1]
-pSliceA[j*imageWidth+k+1];
dz[6]=pSliceD[(j+1)*imageWidth+k+1]
-pSliceA[(j+1)*imageWidth+k+1];
dz[7]=pSliceD[(j+1)*imageWidth+k]
-pSliceA[(j+1)*imageWidth+k];

//計算三角形頂點的坐標和梯度
vertPos=0;
facePos=0;
for(w=0;w<12;w++)
{
if(g_EdgeTable[cubeType]&(1<<w)) //what …..
{
//根據g_edgeTable[256]對應值判斷cube的那一條邊與等值面有交點
switch(w)
{
case 0:
offset=j*imageWidth+k;
edgeGroup=bottomXEdge;
break;
case 1:
offset=j*imageWidth+k+1;
edgeGroup=bottomYEdge;
break;
case 2:
offset=(j+1)*imageWidth+k;
edgeGroup=bottomXEdge;
break;
case 3:
offset=j*imageWidth+k;
edgeGroup=bottomYEdge;
break;
case 4:
offset=j*imageWidth+k;
edgeGroup=topXEdge;
break;
case 5:
offset=j*imageWidth+k+1;
edgeGroup=topYEdge;
break;
case 6:
offset=(j+1)*imageWidth+k;
edgeGroup=topXEdge;
break;
case 7:
offset=j*imageWidth+k;
edgeGroup=topYEdge;
break;
case 8:
offset=j*imageWidth+k;
edgeGroup=zEdge;
break;
case 9:
offset=j*imageWidth+k+1;
edgeGroup=zEdge;
break;
case 10:
offset=(j+1)*imageWidth+k+1;
edgeGroup=zEdge;
break;
case 11:
offset=(j+1)*imageWidth+k;
edgeGroup=zEdge;
break;

}//對應switch的{。。。end for//根據g_EdgeTable對應值判斷cube的那一條邊與等值面有交點
//該邊上的頂點是否已經在上一層中生成
if(edgeGroup[offset]==-1)
{
int index1,index2;
short s1,s2,s;
float x1,y1,z1,nx1,ny1,nz1;
float x2,y2,z2,nx2,ny2,nz2;
//得到該邊兩端點的索引進而得到兩點的灰度值
index1=g_CoordTable[w][3];
index2=g_CoordTable[w][4];
s1=cubegrid[index1];
s2=cubegrid[index2];
if(s1<highThreshold&&s1>lowThreshold)
{
if(s2>=highThreshold)
{
s=highThreshold;
}
else if(s2<=lowThreshold)
{
s=lowThreshold;
}
}
else if(s2<highThreshold&&s2>lowThreshold)
{
if(s1>=highThreshold)
{
s=highThreshold;
}
else if(s1<=lowThreshold)
{
s=lowThreshold;
}
}
//計算兩端點實際坐標
x1=(k+g_CoordVertex[index1][0])*XSpace;
y1=(j+g_CoordVertex[index1][1])*YSpace;
z1=(i+g_CoordVertex[index1][2])*ZSpace;
x2=(k+g_CoordVertex[index2][0])*XSpace;
y2=(j+g_CoordVertex[index2][1])*YSpace;
z2=(i+g_CoordVertex[index2][2])*ZSpace;
//計算兩端點的法向量

nx1=dx[index1]/XSpace;
ny1=dy[index1]/YSpace;
nz1=dz[index1]/ZSpace;
nx2=dx[index2]/XSpace;
ny2=dy[index2]/YSpace;
nz2=dz[index2]/ZSpace;
float factor=((float)(s-s1))/((float)(s2-s1));

//插值計算交點坐標
vertPoint[vertPos][0]=factor*(x2-x1)+x1;
vertPoint[vertPos][1]=factor*(y2-y1)+y1;
vertPoint[vertPos][2]=factor*(z2-z1)+z1;
//計演算法向量
vertPoint[vertPos][3]=factor*(nx1-nx2)-nx1;
vertPoint[vertPos][4]=factor*(ny1-ny2)-ny1;
vertPoint[vertPos][5]=factor*(nz1-nz2)-nz1;
//法向量歸一化
squaroot=sqrt(vertPoint[vertPos][3]*vertPoint[vertPos][3]+vertPoint[vertPos][4]*vertPoint[vertPos][4]
+vertPoint[vertPos][5]*vertPoint[vertPos][5]);
if(squaroot<=0)squaroot=1.0;
vertPoint[vertPos][3]/=squaroot;
vertPoint[vertPos][4]/=squaroot;
vertPoint[vertPos][5]/=squaroot;
//更新包圍盒數據
if(min[0]>vertPoint[vertPos][0])
{
min[0]=vertPoint[vertPos][0];
}
if(min[1]>vertPoint[vertPos][1])
{
min[1]=vertPoint[vertPos][1];
}
if(min[2]>vertPoint[vertPos][2])
{
min[2]=vertPoint[vertPos][2];
}
if(max[0]<vertPoint[vertPos][0])
{
max[0]=vertPoint[vertPos][0];
}
if(max[1]<vertPoint[vertPos][1])
{
max[1]=vertPoint[vertPos][1];
}
if(max[2]<vertPoint[vertPos][2])
{
max[2]=vertPoint[vertPos][2];
}
//記錄新生成的頂點索引
cellVerts[w]=m_vNumber;
edgeGroup[offset]=cellVerts[w];
m_vNumber++;
vertPos++;
} //end if(edgeGroup[offset]==-1) ////
else
{
//若該點已經在上一層生成,則直接得到其索引
cellVerts[w]=edgeGroup[offset];
}
} // end對應if(g_EdgeTable[cubeType]&(1<<w)) //

} //對應for(w=0;w<12;w++)
//保存當前cubes 頂點和法向量
tt1=m_vNumber-vertPos;
for(tt=0;tt<vertPos;tt++)
{
vPointNomal[tt1+tt][0]=vertPoint[tt][0];
vPointNomal[tt1+tt][1]=vertPoint[tt][1];
vPointNomal[tt1+tt][2]=vertPoint[tt][2];
vPointNomal[tt1+tt][3]=vertPoint[tt][3];
vPointNomal[tt1+tt][4]=vertPoint[tt][4];
vPointNomal[tt1+tt][5]=vertPoint[tt][5];
}
// memcpy(vPointNomal+6*(m_vNumber-vertPos) ,vertPoint,sizeof(float)*6*vertPos);
//記錄新生成的三角面片數據
w=0;
while (g_TriTable[cubeType][w]!=-1)
{
for(r=0;r<3;r++)
{
triIndex[facePos][r]=cellVerts[g_TriTable[cubeType][w++]];
if(triIndex[facePos][r]<0)
{
AfxMessageBox("有問題",MB_OK,0);
}
}
facePos++;
m_fNumber++;

} //end 對應while (g_TriTable[cubeType][w]!=-1)
//保存面數據
tt1=m_fNumber-facePos;
for(tt=0;tt<facePos;tt++)
{
pFace[tt1+tt][0]=triIndex[tt][0];
pFace[tt1+tt][1]=triIndex[tt][1];
pFace[tt1+tt][2]=triIndex[tt][2];
}
// memcpy(pFace+3*(m_fNumber-facePos)*sizeof(long),triIndex,sizeof(int)*3*facePos);
} memcpy(bottomXEdge,topXEdge,sizeof(short)*imageSize);
memcpy(bottomYEdge,topYEdge,sizeof(short)*imageSize);
memset(topXEdge,-1,sizeof(short)*imageSize);
memset(topYEdge,-1,sizeof(short)*imageSize);
memset(zEdge,-1,sizeof(short)*imageSize);
}
delete []tempSlice;
delete []bottomXEdge;
delete []bottomYEdge;
delete []topXEdge;
delete []topYEdge;
delete []zEdge;

return 1;
}
在OnDraw
glBegin(GL_TRIANGLES);
for(i=0;i<pDoc->m_fNumber;i++)
{
glNormal3fv(&(pDoc->vPointNomal[pDoc->pFace[ i][0]][3]));
glVertex3fv(&(pDoc->vPointNomal[pDoc->pFace[ i][0]][0]));

glNormal3fv(&(pDoc->vPointNomal[pDoc->pFace[ i ][1]][3]));
glVertex3fv(&(pDoc->vPointNomal[pDoc->pFace[ i ][1]][0]));

glNormal3fv(&(pDoc->vPointNomal[pDoc->pFace[ i ][2]][3]));
glVertex3fv(&(pDoc->vPointNomal[pDoc->pFace[ i ][2]][0]));
}

glEnd();
以上代碼只用於理解,未測試

㈨ 三維坐標系同時繞三個軸旋轉

我粗略算了一下,好想是arccos(cosa*cosb).演算法是這樣的.首先設最初三個軸的單位矢為i,j,k轉過後a變為i1,j1,k1.再轉過b後變為i2,j2,k2.這樣,容易得到,轉過a後k1=cosa*k-sina*i
j1=j.轉過b後k2=cosb*k1+sinb*j1.最後,要算的兩個平面的夾角其實就是他們法向的夾角.把k與k2點乘一下,再除他們的模就行了.

㈩ 旋度怎麼計算

是這樣算的:
先說一般演算法:假設(變)向量A={P(X,Y,Z),Q(X,Y,Z),R(X,Y,Z)}
規定A的旋度=一個向量,這個向量的三個坐標分別是:
第一個坐標=偏R/偏y-偏Q/偏z
第二個坐標=偏P/偏z-偏R/偏x
第三個坐標=偏Q/偏x-偏P/偏y。

具體到這個題,對號入座,則其中P=z+siny,Q=xcosy-z,R=0,於是
第一個坐標=偏(0)/偏y-偏(xcosy-z)/偏z=1
第二個坐標=偏(z+siny)/偏z-偏(0)/偏x=1
第三個坐標=偏(xcosy-z)/偏x-偏(z+siny)/偏y=cosy-cosy=0。

旋度
旋度是向量分析中的一個向量運算元,可以表示三維向量場對某一點附近的微元造成的旋轉程度。 這個向量提供了向量場在這一點的旋轉性質。旋度向量的方向表示向量場在這一點附近旋轉度最大的環量的旋轉軸,它和向量旋轉的方向滿足右手定則。旋度向量的大小則是繞著這個旋轉軸旋轉的環量與旋轉路徑圍成的面元的面積之比。舉例來說,假設一台滾筒洗衣機運行的時候,從前方看來,內部的水流是逆時針旋轉,那麼中心水流速度向量場的旋度就是朝前方向外的向量。

閱讀全文

與三維旋轉演算法相關的資料

熱點內容
php自適應網站 瀏覽:467
2b2t伺服器怎麼獲得許可權 瀏覽:815
c語言javaphp 瀏覽:804
程序員技術不分高低嗎 瀏覽:619
dos不是內部或外部命令 瀏覽:708
PC機與單片機通訊 瀏覽:675
二級加密圖 瀏覽:113
壓縮機異音影響製冷嗎 瀏覽:711
德斯蘭壓縮機 瀏覽:490
程序員太極拳視頻 瀏覽:531
網上購買加密鎖 瀏覽:825
安卓為什麼軟體要隱私 瀏覽:83
虛擬主機管理源碼 瀏覽:811
java圖形圖像 瀏覽:230
單片機輸出口電平 瀏覽:486
java配置資料庫連接 瀏覽:479
java多態的體現 瀏覽:554
java的split分隔符 瀏覽:128
跪著敲代碼的程序員 瀏覽:239
web和php有什麼區別 瀏覽:120