計算機圖形學-實驗5-掌握Bezier樣條曲面生成思想、複習基本圖元繪製、互動操作和幾何變換相關內容
阿新 • • 發佈:2019-01-22
實驗五:(2學時)
一、 實驗目的:
掌握Bezier樣條曲面生成思想、複習基本圖元繪製、互動操作和幾何變換相關內容
二、 實驗內容:
1、在視窗中畫三維座標,包括原點和三個座標軸;
2、畫一條Bezier樣條曲面,包含4*4個控制點;
3、利用滑鼠或鍵盤控制曲面在螢幕上移動、旋轉和放縮;
4、用滑鼠調整控制點的位置,觀察曲面變化
三、 實現效果及步驟(或流程)
1、在視窗中畫三維座標,包括原點和三個座標軸;
a) 實現效果:
b) 實現步驟:
(1)畫原點
//原點 glColor3d(0.0, 1.0, 0.0); glBegin(GL_POINTS); glVertex3f(0, 0, 0); glEnd();
(2)畫x軸以及標識
//畫x軸 glColor3d(1.0, 0.0, 0.0); glBegin(GL_LINES); glVertex3f(-linex1, liney1, linez1); glVertex3f(linex1, liney1, linez1); glEnd(); //畫x標識 glBegin(GL_LINES); glVertex3f(linex1 + 5, liney1, linez1); glVertex3f(linex1 + 15, liney1 - 10, linez1); glEnd(); glBegin(GL_LINES); glVertex3f(linex1 + 5, liney1 - 10, linez1); glVertex3f(linex1 + 15, liney1, linez1); glEnd();
(3)畫y軸以及標識
//畫y軸 glColor3d(0.0, 1.0, 0.0); glBegin(GL_LINES); glVertex3f(linex2, -liney2, linez2); glVertex3f(linex2, liney2, linez2); glEnd(); //畫y標識 glBegin(GL_LINES); glVertex3f(linex2 - 10, liney2 + 5, linez2); glVertex3f(linex2 - 5, liney2, linez2); glEnd(); glBegin(GL_LINES); glVertex3f(linex2, liney2 + 5, linez2); glVertex3f(linex2 - 5, liney2, linez2); glEnd(); glBegin(GL_LINES); glVertex3f(linex2 - 5, liney2 - 7, linez2); glVertex3f(linex2 - 5, liney2, linez2); glEnd();
(4)畫z軸以及標識
//z軸 藍
glColor3d(0.0, 0.0, 1.0);
glBegin(GL_LINES);
glVertex3f(linex3, liney3, -linez3);
glVertex3f(linex3, liney3, linez3);
glEnd();
//畫z
glBegin(GL_LINES);
glVertex3f(linex3 + 2, liney3, linez3);
glVertex3f(linex3 + 12, liney3, linez3);
glEnd();
glBegin(GL_LINES);
glVertex3f(linex3 + 2, liney3 - 7, linez3);
glVertex3f(linex3 + 12, liney3, linez3);
glEnd();
glBegin(GL_LINES);
glVertex3f(linex3 + 2, liney3 - 7, linez3);
glVertex3f(linex3 + 12, liney3 - 7, linez3);
glEnd();
2、畫一條Bezier樣條曲面,包含4*4個控制點;
a) 實現效果:
b) 實現步驟:
(1)初始化座標
//初始座標
GLfloat ctrlPts[4][4][3] = { { { -45, -45, 120 },{ -15, -45, 60 },{ -15, -45, -30 },{ 45, -45, 60 } },{ { -45, -15, 30 },{ -15, -15, 90 },{ 15, -15, 0.0 },{ 45, -15, -30 } },{ { -45, 15, 120 },{ -15, 15, 0.0 },{ 15, 15, 90 },{ 45, 15, 120 } },{ { -45, 45, -60 },{ -15, 45, -60 },{ 15, 45, 0.0 },{ 45, 45, -30 } } };
(2)畫曲面
//畫曲面
for (j = 0; j <= 10; j++)
{
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 10; i++)
{
glEvalCoord2f((GLfloat)i / 10.0, (GLfloat)j / 10.0);
//呼叫求值器
}
glEnd();
glBegin(GL_LINE_STRIP);
for (i = 0; i <= 10; i++)
{
//呼叫求值器
glEvalCoord2f((GLfloat)j / 10.0, (GLfloat)i / 10.0);
}
glEnd();
}
(3)畫控制點
//畫控制點
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
glPointSize(4);
glColor3d(1.0, 0.0, 0.0);
//選中則為藍色
if (i == switchx&&j == switchy)
{
glColor3d(0.0, 0.0, 1.0);
}
glBegin(GL_POINTS);
glVertex3f(ctrlPts[i][j][0], ctrlPts[i][j][1], ctrlPts[i][j][2]);
glEnd();
}
}
3、利用滑鼠或鍵盤控制曲面在螢幕上移動、旋轉和放縮;
a) 實現效果:
b) 實現步驟:
(1)自定義平移函式
//自定義平移函式
void translate3D(GLfloat tx, GLfloat ty, GLfloat tz) {
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 3; k++)
{
if (k == 0)
{
ctrlPts[i][j][k] += tx* 0.01;
}
else if (k == 1)
{
ctrlPts[i][j][k] += ty* 0.01;
}
else if (k == 2)
{
ctrlPts[i][j][k] += tz * 0.01;
}
}
}
}
}
(2)自定義旋轉函式
//自定義旋轉函式
void Rotate3D(GLfloat inx, GLfloat iny)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
xx = ctrlPts[i][j][0];
yy = ctrlPts[i][j][1];
zz = ctrlPts[i][j][2];
ctrlPts[i][j][1] = yy*cos(iny*pi / 180) + zz*sin(iny*pi / 180);
ctrlPts[i][j][2] = -yy*sin(iny*pi / 180) + zz*cos(iny*pi / 180);
zz = ctrlPts[i][j][2];
ctrlPts[i][j][2] = zz*cos(inx*pi / 180) - xx*sin(inx*pi / 180);
ctrlPts[i][j][0] = zz*sin(inx*pi / 180) + xx*cos(inx*pi / 180);
}
}
}
(3)自定義放縮函式
void scale3D(GLfloat zoom)
{
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
for (int k = 0; k < 3; k++)
{
if (k == 0)
{
ctrlPts[i][j][k] *= zoom;
}
else if (k == 1)
{
ctrlPts[i][j][k] *= zoom;
}
else if (k == 2)
{
ctrlPts[i][j][k] *= zoom;
}
}
}
}
}
4、用滑鼠調整控制點的位置,觀察曲面變化
a) 實現效果:
b) 實現步驟:
//獲取點拖拽起始點
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < 4; j++)
{
if ((ctrlPts[i][j][0] - x + 250) >= -5 && (ctrlPts[i][j][0] - x + 250) <= 5)
{
if ((ctrlPts[i][j][1] - 250 + y) >= -5 && (ctrlPts[i][j][1] - 250 + y) <= 5)
{
oldx = x;
oldy = 500 - y;
switchx = i;
switchy = j;
changeMode = 1;
}
}
}
}
//獲取點拖拽終點
if (changeMode == 1)
{
nowx = x;
nowy = 500 - y;
ctrlPts[switchx][switchy][0] += nowx - oldx;
ctrlPts[switchx][switchy][1] += nowy - oldy;
oldx = x;
oldy = 500 - y;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
//重新繪製
glutPostRedisplay();
}