人體骨骼模型的人體骨骼尺寸
人體骨骼尺寸規格尺寸:有170cm 130cm 85cm 65cm 45cm 20cm的。各種規格的人體骨骼模型不只是比例的區別,如85cm的就有硬脊椎的和軟脊椎的,130cm和170cm的骨骼模型顯示神經分支、脊椎動脈和腰椎間盤等。頭顱含可活動的下巴、可移動的頭顱蓋、骨縫線和3顆可取下的下牙。
170公分高的人體骨骼模型有些附帶內臟、血管、神經、動靜脈等,可以真實地演示人體骨骼模型的構造。
人體骨骼模型與人體軀干模型同樣屬于醫學教學模型。試用于中專、醫學院等在講解人體解剖時使用,直觀性強。
人體骨骼模型有國產人體骨骼和國外進口人體骨骼模型。
人體骨骼模型170CM,手臂和腿部可拆下供研究。顯示神經分支、脊椎動脈和腰椎間盤等。鐵制底座 ,架子和五金配件全部采用不銹鋼 .用PVC制成.
尺寸: 170CM
人體骨骼模型85cm,模擬人體運動,直觀性強。它讓孩子們有興趣學習骨頭的名稱,使學生、醫生和其他對模型感興趣者感到滿意。頭顱蓋可取下。安放在鐵座上。尺寸:85CM 。
人體骨骼帶分椎間盤模型85CM,這款貴重的教學模型顯示脊椎、神經根、脊椎動脈、分椎間盤、用綠色加深的胸部軟骨、可分成3件的頭顱和手足。這款精確的模型包含成人的200塊骨頭,四肢可彎曲到任何自然的狀態,除手足外全部用關節連接。這款受歡迎的案頭模型適用于康復治療、理療和運動醫學專業使用。鐵質座。尺寸:85CM。
人體骨骼散骨模型(游離骨),材質PVC。
買人體骨骼模型有用嗎
買人體骨骼模型用處不大,想要加深記憶,多去幾次實驗室就行,你也可以買些圖冊什么的來看,一本是人體實用彩圖,一本是標本的實物圖。 而且,各人認為,看模型遠沒有看真實的骨骼標本有意義,因為不同人之間是有很大差異的,骨頭也是,比如說骶骨,五合一,我見的那個標本是六合一。
人體骨骼和人體骨骼模型用英語怎么說?骨骼要加復數嗎?
人體骨骼 Human Skeleton
人體骨骼模型 Artificial Human Skeleton
作為人體骨骼的整體概念而言不用加復數,如果強調是多種骨骼可以加復數.
bone 如果是指多個骨頭的話就必須加復數
如何做人體骨架模型?
本文提供一種將骨架動作矢量映射到人體骨架模型的一種方法,通過輸入各個骨骼的當前方向,反饋給骨架模型,這樣就實現了動畫的效果。實驗開發工具是VC6.0在OpenGL平臺上開發完成。
閱讀對象:
假定讀者已經熟悉OpenGL編程,就算不熟悉,只要了解基本的旋轉,平移,堆棧操作就好。
假定讀者已經了解基本的c++編程,其中需要了解遞歸的算法,遞歸的方法請參考一下數據結構吧。
制作過程:
第一步,3D模型準備
這一步驟的目的是提供分解的骨骼模型,它需要導出多個組成身體結構的文件,模型可以不用自己制作,只要到網上找找吧,應該很多,最好是是人體模型,如果用動物的模型也可以,不過需要自己定義映射骨架了,比如圖中的骷髏模型是我從人體動畫軟件por 5.0找到的。然后使用3d max 將身體的各個部位導出為3ds文件,這個步驟很簡單,也不需要有什么3d max的基礎。這里有一個小的技巧就是可以選中多個部分作為一個3ds模型導出,比如我需要將左右肩胛骨與脊椎骨肋骨作為同一個部分導出,這樣可以將它命名為身體軀干(body)。這樣我們就準備了各個3ds文件了,分別是:
身體軀干 BODY.3DS
頭部 HEAD.3DS
左臂 LSHOULDER.3DS
右臂 RSHOULDER.3DS
左小臂 LELBOW.3DS
右小臂 RELBOW.3DS
左大腿 LTHIGH.3DS
右大腿 RTHIGH.3DS
左小腿 LFEET.3DS
右小腿 RFEET.3DS
這樣這些組成部分就可以靈活的拼接出一個人體來了。
第二步,定義相關的核心數據結構
為了得到運動的各個身體部分數據信息,我們需要存儲一些運動信息,主要有:
骨骼ID
骨骼關節的當前位置;r_x,r_y,r_z
骨骼之間的關系,例如手臂是軀干的延伸,而左小臂是左臂的延伸;PID,CID
我們可以通過下圖來了解骨骼之間的結構關系
存放3ds文件位置;file_name_3ds
3ds模型的初始化方向;這個是比較抽象一點的概念,它是指從父節點指向子節點的方向,例如左小臂的初始位置是平放向下,那么對應的矢量就是 (-0.2,-1,0)
以下是數據結構部分:
class bone
{
public:
int y;
int x;
int r_z; //現實世界z坐標
int r_y;
int r_x;
int rotated_X; //旋轉后的坐標
int rotated_Y;
int is_marked; //是否已經標記
int PID; //父節點
int CID; //子節點,目前針對軸關節和膝蓋有效
float start_arc_x,end_arc_x; //相對父節點的x 左右方向轉動角度限制
float start_arc_y,end_arc_y; //相對父節點的y 上下方向轉動角度限制
float start_arc_z,end_arc_z; //相對父節點的z 前后方向轉動角度限制
double LengthRatio;
char name[80]; //名稱
char file_name_3ds[180]; //3ds文件名稱
int ID;
bone(int ID,char *name,int PID);
virtual ~bone();
float bone_init_x,bone_init_y,bone_init_z; //初始化骨骼的矢量方向,3d max 模型
};
第三步,初始化骨架結構
在定義了bone的結構以后,我們定義一個skeleton類來在第一次初始化時加載這些結構,
obone = bone (2,"head",1); //定義一個bone
strcpy(obone.file_name_3ds,"head.3DS"); //設置它的3ds文件名
obone.bone_init_x = 0; //初始化骨骼的矢量方向
obone.bone_init_y = 1;
obone.bone_init_z = 0;
bonevec.push_back (obone); //放入vector結構,這里用到了STL編程技術中的vector
以下是實現的部分代碼:
skelecton::skelecton()
{
float fy = 0.56f ;
float ftx = 0.19f;
float ffx = 0.08f;
bone obone = bone (1,"neck",0);
bonevec.push_back (obone);
obone = bone (2,"head",1);
strcpy(obone.file_name_3ds,"head.3DS");
obone.bone_init_x = 0;
obone.bone_init_y = 1;
obone.bone_init_z = 0;
bonevec.push_back (obone);
obone = bone (3,"rShoulder",1);
bonevec.push_back (obone);
obone = bone (4,"lShoulder",1);
bonevec.push_back (obone);
obone = bone (5,"rElbow",3);
strcpy(obone.file_name_3ds,"rShoulder.3DS");
obone.bone_init_x = fy;
obone.bone_init_y = -1;
obone.bone_init_z = 0;
obone.CID = 7;
bonevec.push_back (obone);
obone = bone (6,"lElbow",4);
strcpy(obone.file_name_3ds,"lShoulder.3DS");
obone.bone_init_x = -fy;
obone.bone_init_y = -1;
obone.bone_init_z = 0;
obone.CID = 8;
bonevec.push_back (obone);
//.............太長只給出部分的代碼..........................
}
第四步,學習3ds公共的類CLoad3DS,可以用來載入顯示模型
這個類是公用一個類,詳細的類CLoad3DS的接口信息可以到一個open source項目里參考。http://scourge.sourceforge.net
http://scourge.sourceforge.net/api/3ds_8h-source.html
實際上在使用這個類時候,我做了一些修改,加了得到最大頂點的方法。這個在第五步會說明。
我們定義一個OpenGL的類來做模型控制類,負責載入模型,
CLoad3DS* m_3ds;
int OpenGL::Load3DS(int ID, char *filename)
{
if(m_3ds!=NULL) m_3ds->Init(filename,ID);
return 0;
}
然后在顯示時候調用
int OpenGL::show3ds(int ID)
{
m_3ds->show3ds(ID,0,0,0,2);
return 0;
}
第五步,使用遞歸方法分層次載入模型
這里是重點的內容了,讓我們思考一些問題,實現骨骼會隨著輸入的方向而改變方向,需要做那些事情呢?
首先針對一塊骨骼來考慮:
第一,我們需要讓骨骼繞著它的節點旋轉到輸入的方向上
第二,我們需要知道骨骼目前節點的位置,才能旋轉??墒俏覀冎拦趋罆母腹趋擂D動的,例如左小臂會跟著左臂轉動,當身體轉動時左臂也會跟著身體轉動的,這里看起來像是有一個父子連動的關系,所以當前節點的位置會與它的父骨骼有關,父骨骼轉動的角度,子骨骼也必須轉動,所以這里自然想到了遞歸模型了,至于如何存儲這些轉動過程呢,還好openGL提供了glPushMatrix();glPopMatrix();那么所有的子骨骼必須包含在父骨骼的glPushMatrix();glPopMatrix();好了,這個變成
//遞歸實現3d現實
int skelecton::Render_skeleton_3D(int ID)
{
glPushMatrix(); //開始記錄堆棧
joint_point = pgl->get_joint_point(ID); //找到節點位置
glTranslatef(joint_point.x,joint_point.y,joint_point.z); //坐標移到節點位置
pgl->rotate_bone (vt1,vt2,vto); //旋轉骨骼到指定的方向
glTranslatef(-joint_point.x,-joint_point.y,-joint_point.z);//坐標移回來
pgl->show3ds(ID); //顯示模型
//遍歷子節點
for (theIterator = bonevec.begin(); theIterator != bonevec.end(); theIterator++)
{
pbone = theIterator;
if((pbone->PID == ID) )
{
Render_skeleton_3D(pbone->ID); //遞歸調用
}
}
glPopMatrix(); //退出記錄堆棧
}
剩下需要解決的問題就是如何找到節點位置。
尋找節點位置,我們看到上面代碼 get_joint_point(ID)就是找到節點了,其實如果不追求高的準確度,我們可以假設每個模型的最高的點即為骨骼的節點,當然這個假設前提是人體模型是正面站立的,手臂自然垂下,這樣可以近似認為每個模型的最高的點即為骨骼的節點,這樣函數就很簡單了,這個方法是修改了Cload3ds類的方法,如下:
Vector3f CLoad3DS::get_joint_point(int j0)
{
CVector3 LastPoint;
Vector3f vect;
LastPoint.y = -1000 ;
if(j0==2) LastPoint.y = 1000 ;//頭部節點朝下
// 遍歷模型中所有的對象
for(int l = 0; l < g_3DModel[j0].numOfObjects; l++)
{
if(g_3DModel[j0].pObject.size() <= 0) break;// 如果對象的大小小于0,則退出
t3DObject *pObject = &g_3DModel[j0].pObject[l];// 獲得當前顯示的對象
for(int j = 0; j < pObject->numOfFaces; j++) // 遍歷所有的面
{
for(int tex = 0; tex < 3; tex++) // 遍歷三角形的所有點
{
int index = pObject->pFaces[j].vertIndex[tex]; // 獲得面對每個點的索引
if(j0==2)
{
if(pObject->pVerts[index].y < LastPoint.y )
LastPoint = pObject->pVerts[index];
}
el
{
if(pObject->pVerts[index].y > LastPoint.y )
LastPoint = pObject->pVerts[index];
}
}
}
}
vect.x = LastPoint.x ;
vect.y = LastPoint.y ;
vect.z = LastPoint.z ;
return vect;
}
比較特殊的是頭部節點是通過脖子連接的,所以它是取最低的點。
現在解決最后的問題了,如何旋轉了,具體來講就是骨骼從原來自然的狀態旋轉到目前的方向,例如手臂從自然垂下變成抬起,垂下和抬起兩個狀態的矢量是不同的方向的,如何旋轉呢? 這里就要用到了空間幾何里的點積和叉積的概念了,簡單來講就是利用點積來求矢量夾角余弦,利用叉積來求兩個矢量的法向量,如果你忘記了這些概念,可以回去參考一下高等數學書,這個連接也提供了一些資料,可以幫助理解http://www.gameres.com/Articles/Program/Visual/Other/shiliang.htm
然后呢,我們知道了兩個矢量的夾角與它們的法向量,下面的事情就變得簡單了,我們讓骨骼原來的矢量以法向量為旋轉軸,旋轉一定角度,這個角度就是兩個矢量的夾角,這樣問題就解決了,所以這里的代碼如下:
int OpenGL::rotate_bone(Vector3f vVector1, Vector3f vVector2, Vector3f vVectorOrgin)
{
Vector3f vt1 = Vector3f(vVector1.x,vVector1.y,vVector1.z);
Vector3f vt2 = Vector3f(vVector2.x,vVector2.y,vVector2.z);
Vector3f vt4 = vt2-vt1;
double arc12 = AngleBetweenVectors(vVectorOrgin,vt4);
double rarc12 = 180*arc12/pi;
float len= Distance(vt1,vt2);
Vector3f vt3 = Cross(vVectorOrgin,vt4);
glRotatef ((float)rarc12,vt3.x,vt3.y,vt3.z);
return 0;
}