如圖所示:
下面來介紹我們主要使用的幾個OpenGL函數:
auxSolidCylinder(GLfloat radius,GLfloat length)
繪製的圓柱的上底面是固定的,而且是固定在當前座標系中y=1.0f的平面上,以y軸爲軸,隨着指定高度的不同不斷地向y軸負方向延伸.(從上圖C點開始繪製)
glTranslatef(GLfloat x,GLfloat y,GLfloat z)
把當前矩陣和一個表示移動物體的矩陣相乘。三個參數分別表示了在三個座標上的位移值。
glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)
把當前矩陣和一個表示旋轉物體的矩陣相乘。物體將繞着(0,0,0)到(x,y,z)的直線以逆時針旋轉,參數angle表示旋轉的角度。
注意:glRotatef()只使物體繞過原點的直線旋轉,所以首先要把座標系移到這個側面的旋轉軸上.
// 起始線段:以C(0,1,0)爲起點,它的長度D(distance)通過目標線段計算,
// 終點座標爲(0,1-distance,0)
// 目標線段:以A(x1,y1,z1)爲起點,以B(x2,y2,z2)爲終點
目的:通過變換矩陣將起始線段CD平移、旋轉到目標線段AB
步驟:
1.根據A、B兩點的座標求出圓柱長度distance,然後就可以求出D點的座標
2.計算CD向量與AB向量的法向量(fx,fy,fz)以及CD與AB的夾角angle
(1).求C'D',其中C'D'//CD,C'與A重合(這樣C'D'和AB就在一個平面上,這兩個空間線段的公共頂點是(2,4,5))
(2).求C'D'和AB表示的“起始向量(sx,sy,sz)”和“目標向量(dx,dy,dz)”
(3).由向量的叉積公式求出向量C'D'和向量AB的法向量(fx,fy,fz)
(4).求出D'B的長度,這樣,三角形AD'B每條邊的長度都已知,根據三角形的餘弦定理,求出角D'AB的度數
3.將起始線段CD的起點移動到原點(0,0,0)
4.使用glRotatef將CD繞着法向量(fx,fy,fz)旋轉angle度,使CD與AB平行,即glRotatef(angel,fx,fy,fz)
5.使用glTranslatef將旋轉後的CD平移到AB位置,平移量爲A點的座標,即glTranslatef(x1,y1,z1)
- // 根據空間兩點繪製圓柱
- void CPipeLineView::DrawChannel(GLfloat x1, GLfloat y1, GLfloat z1, GLfloat x2, GLfloat y2, GLfloat z2 )
- {
- // 起始線段:以(0,1,0)爲起點,它的長度(distance)通過目標線段計算,
- // 終點座標爲(0,1-distance,0)
- // 目標線段:以(x1,y1,z1)爲起點,以(x2,y2,z2)爲終點
- // 計算目標向量
- GLfloat dx = x2 - x1;
- GLfloat dy = y2 - y1;
- GLfloat dz = z2 - z1;
- // 算出目標向量模(即AB長度)
- GLfloat distance = sqrt(dx*dx + dy*dy + dz*dz);
- // 計算平移量
- GLfloat px = x1;
- GLfloat py = y1 - 1;
- GLfloat pz = z1;
- // 起始線段的末端點
- GLfloat bx = px;
- GLfloat by = (1-distance) + py;
- GLfloat bz = pz;
- // 計算起始向量
- GLfloat sx = bx - x1;
- GLfloat sy = by - y1;
- GLfloat sz = bz - z1;
- // 計算向量(sx,sy,sz)與向量(dx,dy,dz)的法向量(sy*dz - dy*sz,sz*dx - sx*dz,sx*dy - dx*sy)
- GLfloat fx = sy*dz - dy*sz;
- GLfloat fy = sz*dx - sx*dz;
- GLfloat fz = sx*dy - dx*sy;
- // 求兩向量間的夾角
- // 計算第三條邊的長度
- GLfloat ax = fabs(x2 - bx);
- GLfloat ay = fabs(y2 - by);
- GLfloat az = fabs(z2 - bz);
- GLfloat length = sqrt(ax*ax + ay*ay + az*az);
- // 根據餘弦定理計算夾角
- GLfloat angle = acos((distance*distance*2 - length*length)/(2*distance*distance))*180.0f/3.14159;
- // 繪製第一個點A
- glPushMatrix();
- glTranslatef(x1,y1,z1);
- auxSolidSphere(1);
- glPopMatrix();
- // 繪製圓柱
- glPushMatrix();
- // 變換的順序與函數書寫的順序相反,
- // 即先平移(0,-1,0),再繞法向量旋轉,最後再平移
- glTranslatef(x1,y1,z1);
- glRotatef(angle,fx,fy,fz);
- glTranslatef(0,-1,0);
- auxSolidCylinder(0.5,distance);
- glPopMatrix();
- // 繪製第二個點B
- glPushMatrix();
- glTranslatef(x2,y2,z2);
- auxSolidSphere(1);
- glPopMatrix();
- };
調用方法:
- DrawChannel(2,4,5,12,5,15);
運行效果:
OK,OpenGL剛入門不久,請大家多多指教!