1. 程式人生 > >計算機圖形學-實驗5-掌握Bezier樣條曲面生成思想、複習基本圖元繪製、互動操作和幾何變換相關內容

計算機圖形學-實驗5-掌握Bezier樣條曲面生成思想、複習基本圖元繪製、互動操作和幾何變換相關內容

實驗五: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();
}