電腦圖學
第四週-Week04
(1) 複習上週的進度: move 移動
(2) 主題: 移動、旋轉、縮放
(3) 範例 : Transformation.exe
(4) 期中考題
範例練習
(1)到 jsyeh.org/3dcg10下載 windows.zip / data.zip / glut.dll (詳見圖一、圖二)
(圖一)
(圖二)
試著玩玩看glRotatef(角度, x軸, y軸, z軸) (請見圖三)
(圖三)出處:老師用圖
旋轉概念可以參照右手安培定則,以方便了解 (請見圖四)
(圖四)出處:老師用圖
重要觀念複習
(詳見圖五)
(圖五)出處:老師用圖
旋轉茶壺(陽春版)
問題點: 程式開太多旋轉速度會不固定 (請見圖六)
#include <stdio.h>
#include <GL/glut.h>
float angle=0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle,0,0,1);
glutSolidTeapot(0.3);
glPopMatrix();
glutSwapBuffers();
printf("%.1f\n", angle);
angle++;
}
int main(int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("week04 transformation");
glutIdleFunc(display);
glutDisplayFunc(display);
glutMainLoop();
}
(圖六)
旋轉茶壺(加強版)
詳見(圖七)
#include <stdio.h>
#include <GL/glut.h>
float angle=0;
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix(); ///備份矩陣
glRotatef(angle,0,0,1); ///旋轉angle度
glutSolidTeapot(0.3);
glPopMatrix(); ///還原矩陣
glutSwapBuffers();
///printf("%.1f\n", angle);
///angle++;
}
void mouse(int button, int state,int x, int y)
{
}
void motion(int x,int y)
{ ///當mouse在drag motion時,
angle=x; ///去改變angle值
glutPostRedisplay(); ///請畫面重畫
}
int main(int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("Week04 transformation");
glutMouseFunc(mouse);
glutMotionFunc(motion);
///glutIdleFunc(display); ///很閒 /Idle,去重畫
glutDisplayFunc(display);
glutMainLoop();
}
(圖七)
旋轉茶壺(最終版)
詳見(圖八)
#include <stdio.h>
#include <GL/glut.h>
float angle=0, teapotX=0, teapotY=0;///加上移動的座標
int oldX=0,oldY=0, nowRotate=0; ///0: translate, 1: rotate
void display()
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glPushMatrix(); ///備份矩陣
glTranslatef(teapotX, teapotY,0); ///我們把轉完的茶壺再移動
glRotatef(angle,0,0,1); ///旋轉angle度
glutSolidTeapot(0.3);
glPopMatrix(); ///還原矩陣
glutSwapBuffers();
///printf("%.1f\n", angle);
///angle++;
}
void mouse(int button, int state,int x, int y)
{
if(button==GLUT_LEFT_BUTTON && state==GLUT_DOWN) nowRotate=1; ///如果是左鍵就旋轉
if(button==GLUT_RIGHT_BUTTON && state==GLUT_DOWN) nowRotate=0; ///如果是右鍵就移動
oldX=x; oldY=y;
}
void motion(int x,int y)
{ ///當mouse在drag motion時,
if(nowRotate==1) angle+=(x-oldX);///angle=x; ///去改變angle值
else{
teapotX+=(x-oldX)/150.0; /// 加上改變量
teapotY+=(oldY-y)/150.0; /// 加上改變量
}
oldX=x; oldY=y;
glutPostRedisplay(); ///請畫面重畫
}
int main(int argc, char *argv[])
{
glutInit(&argc,argv);
glutInitDisplayMode(GLUT_DOUBLE|GLUT_DEPTH);
glutCreateWindow("Week04 transformation");
glutMouseFunc(mouse);
glutMotionFunc(motion);
///glutIdleFunc(display); ///很閒 /Idle,去重畫
glutDisplayFunc(display);
glutMainLoop();
}
(圖八)





沒有留言:
張貼留言