我正在進行一個正在進行的項目,我想要對齊鏈條的鏈接,以便它遵循貝塞爾曲線的輪廓。我目前正在執行以下步驟。如何在OpenGL中圍繞本地軸旋轉對象?
- 繪製曲線。
- 使用顯示列表創建鏈中的一個鏈接。
- 使用FOR循環重複調用計算曲線上兩個點之間角度的函數,返回應該旋轉鏈接的角度和軸。
- 旋轉角度「a」並翻譯到新的位置,將鏈接放置在新的位置。
編輯:我也應該說,兩個半圓環的中心必須位於貝塞爾曲線上。 另外我知道我用來繪製圓環的方法很乏味,以後我會用TRIANGLE_FAN或QUAD_STRIP以更高效的方式繪製圓環。
雖然乍一看這個邏輯看起來好像會正確地呈現鏈條,但最終的結果並不是我想象的那樣。這是一張關於鏈條的圖片。
,我讀了你翻譯的對象旋轉之前的由來?我只需要調用glTranslate(0,0,0),然後從上面的第4步開始?
我已經包括了迄今爲止所做的相關代碼,我將不勝感激任何建議讓我的代碼正常工作。
/* this function calculates the angle between two vectors oldPoint and new point contain the x,y,z coordinates of the two points,axisOfRot is used to return the x,y,z coordinates of the rotation axis*/
double getAxisAngle(pointType oldPoint[],
pointType newPoint[],pointType axisOfRot[]){
float tmpPoint[3];
float normA = 0.0,normB = 0.0,AB = 0.0,angle=0.0;
int i;
axisOfRot->x= oldPoint->y * newPoint->z - oldPoint->z * newPoint->y;
axisOfRot->y= oldPoint->z * newPoint->x - oldPoint->x * newPoint->z;
axisOfRot->z= oldPoint->x * newPoint->y - oldPoint->y * newPoint->x;
normA=sqrt(oldPoint->x * oldPoint->x + oldPoint->y * oldPoint->y + oldPoint->z *
oldPoint->z);
normB=sqrt(newPoint->x * newPoint->x + newPoint->y * newPoint->y + newPoint->z *
newPoint->z);
tmpPoint[0] = oldPoint->x * newPoint->x;
tmpPoint[1] = oldPoint->y * newPoint->y;
tmpPoint[2] = oldPoint->z * newPoint->z;
for(i=0;i<=2;i++)
AB+=tmpPoint[i];
AB /= (normA * normB);
return angle = (180/PI)*acos(AB);
}
/* this function calculates and returns the next point on the curve give the 4 initial points for the curve, t is the tension of the curve */
void bezierInterpolation(float t,pointType cPoints[],
pointType newPoint[]){
newPoint->x = pow(1 - t, 3) * cPoints[0].x +3 * pow(1 - t , 2) * t * cPoints[1].x + 3
* pow(1 - t, 1) * pow(t, 2) * cPoints[2].x + pow(t, 3) * cPoints[3].x;
newPoint->y = pow(1 - t, 3) * cPoints[0].y +3 * pow(1 - t , 2) * t * cPoints[1].y + 3
* pow(1 - t, 1) * pow(t, 2) * cPoints[2].y + pow(t, 3) * cPoints[3].y;
newPoint->z = pow(1 - t, 3) * cPoints[0].z +3 * pow(1 - t , 2) * t * cPoints[1].z + 3
* pow(1 - t, 1) * pow(t, 2) * cPoints[2].z + pow(t, 3) * cPoints[3].z;
}
/* the two lists below are used to create a single link in a chain, I realize that creating a half torus using cylinders is a bad idea, I will use GL_STRIP or TRIANGLE_FAN once I get the alignment right
*/
torusList=glGenLists(1);
glNewList(torusList,GL_COMPILE);
for (i=0; i<=180; i++)
{
degInRad = i*DEG2RAD;
glPushMatrix();
glTranslatef(cos(degInRad)*radius,sin(degInRad)*radius,0);
glRotated(90,1,0,0);
gluCylinder(quadric,Diameter/2,Diameter/2,Height/5,10,10);
glPopMatrix();
}
glEndList();
/*! create a list for the link , 2 half torus and 2 columns */
linkList = glGenLists(1);
glNewList(linkList, GL_COMPILE);
glPushMatrix();
glCallList(torusList);
glRotatef(90,1,0,0);
glTranslatef(radius,0,0);
gluCylinder(quadric, Diameter/2, Diameter/2, Height,10,10);
glTranslatef(-(radius*2),0,0);
gluCylinder(quadric, Diameter/2, Diameter/2, Height,10,10);
glTranslatef(radius,0, Height);
glRotatef(90,1,0,0);
glCallList(torusList);
glPopMatrix();
glEndList();
最後這裏是鏈
t=0.031;
bezierInterpolation(t,cPoints,newPoint);
a=getAxisAngle(oldPoint,newPoint,axisOfRot);
glTranslatef(newPoint->x,newPoint->y,newPoint->z);
glRotatef(a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glCallList(DLid);
glRotatef(-a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glTranslatef(-newPoint->x,-newPoint->y,-newPoint->z);
oldPoint[0]=newPoint[0];
bezierInterpolation(t+=GAP,cPoints,newPoint);
a=getAxisAngle(oldPoint,newPoint,axisOfRot);
glTranslatef(newPoint->x,newPoint->y,newPoint->z);
glRotatef(90,0,1,0);
glRotatef(a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glCallList(DLid);
glRotatef(-a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glRotatef(90,0,1,0);
glTranslatef(-newPoint->x,-newPoint->y,-newPoint->z);
oldPoint[0]=newPoint[0];
bezierInterpolation(t+=GAP,cPoints,newPoint);
a=getAxisAngle(oldPoint,newPoint,axisOfRot);
glTranslatef(newPoint->x,newPoint->y,newPoint->z);
glRotatef(-a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glCallList(DLid);
glRotatef(a,axisOfRot->x,axisOfRot->y,axisOfRot->z);
glTranslatef(-newPoint->x,-newPoint->y,newPoint->z);
我的程序已經包含在main()函數中設置的MODELVIEW語句,正如我在該顯示列表中注意到的列表 「我意識到使用圓柱創建半圓環是一個壞主意,我將使用GL_STRIP或TRIANGLE_FAN一旦我得到對齊的權利「。僅使用圓環不會使鏈條變得逼真,這就是爲什麼選擇使用兩個半圓環和兩個圓柱來創建鏈條的原因。爲簡化起見,我在這篇文章中簡化了取消for循環和大部分main()函數的程序。 感謝您的幫助。 – NeatRobot 2009-11-04 15:38:03
那麼你是否找到了正確的方法來獲得翻譯和輪換工作? – Ketan 2009-11-04 20:39:58
不,我嘗試使用glTranslatef(0,0,0)將初始鏈接移動到原點。然後調用glRotate();然後glTranslate()到原來的位置,然後渲染鏈接,但我仍然有兩個不在曲線上的圓環中心的問題。 – NeatRobot 2009-11-05 13:41:51