2024年4月25日 星期四

從0到0.01的電腦圖學 Week10

本週主題:T-R-T

(1) 主題:T-R-T 關節轉動

(2) 主題:T-R-T 階層性轉動

(3) 小考內容:T-R-T轉動

1. GLUT程式1

將上週 week09-3_glutWireTeapot_glutWireCube_glutWireSphere修改
繪圖塊留下空心方形,程式碼如下:

void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glPushMatrix();

        glutWireCube(0.6);
glPopMatrix();

        glutSwapBuffers();
}

接著修改繪製出身體與手臂,display()與相關函式如下:

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
glPopMatrix();
}
void display(){
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
myBody();
    myArm();
glutSwapBuffers();
}

即可繪製出身體(紅色正方形)與手臂(綠色長方形)。

2. GLUT程式2

加上rotate()涵式使物件可以旋轉,並記得在main中加入glutIdleFunc()函式。

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myBody();
    glPushMatrix();
        glRotatef(angle++, 0 ,0 , 1);
        myArm();
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char*argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week10-2");
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
}

中心長方形依中心轉動

3. GLUT程式3

將上一個程式碼glRotatef()後加入函式glTranslatef()

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myBody();
    glPushMatrix();
        glRotatef(angle++, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char*argv[]){
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("week10-3");
glutDisplayFunc(display);
glutIdleFunc(display);
glutMainLoop();
}
因為移動物件的原因,原來是物件中心在旋轉中心,但這個程式碼會變成物件邊在旋轉中心

4. GLUT程式4:T-R-T關節轉動

將上一個程式碼glRotatef()前加入函式glTranslatef()使其可以是完整的T-R-T結構(綠色處)

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myBody();
    glPushMatrix();
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle++, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char*argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-4");
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMainLoop();
}

5. GLUT程式5:T-R-T階層性轉動

將上一個程式碼中,畫手臂的glPushMatrix(); 與 glPopMatrix();間再插入一整套T-R-T。接著考慮移動(紅色處),就完成階層性轉動。

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myBody();
    glPushMatrix(); ///右半邊
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle++, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();  ///右上手臂
        glPushMatrix();
            glTranslatef(0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(0.15, 0, 0);
            myArm();  ///右下手臂
        glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char*argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-5");
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMainLoop();
}

6. GLUT程式6

在上一個程式碼中已經將右邊的手臂完成,接著我們需要考慮左邊的手臂,也就意味著轉動中心與位移都要改成負的(綠色處)。

#include <GL/glut.h>
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    myBody();
    glPushMatrix(); ///右半邊
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle++, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();  ///右上手臂
        glPushMatrix();
            glTranslatef(0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(0.15, 0, 0);
            myArm();  ///右下手臂
        glPopMatrix();
    glPopMatrix();
    glPushMatrix(); ///左半邊
        glTranslatef(-0.3, 0.3, 0);
        glRotatef(angle, 0 ,0 , 1);
        glTranslatef(-0.15, 0, 0);
        myArm();  ///左上手臂
        glPushMatrix();
            glTranslatef(-0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(-0.15, 0, 0);
            myArm();  ///左下手臂
        glPopMatrix();
    glPopMatrix();
    glutSwapBuffers();
}
int main(int argc, char*argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-6");
    glutDisplayFunc(display);
    glutIdleFunc(display);
    glutMainLoop();
}

7. GLUT程式7:以滑鼠控制轉動
承接上一個程式碼
a.因為要用mouse motion 來操控,所以angle都移除掉++。
b.在main中加入glutMotionFunc(); 啟用鼠標的功能
c.將void motion(int x, int y)函式
#include <GL/glut.h>

void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myBody();

    glPushMatrix(); ///右半邊
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();  ///右上手臂
        glPushMatrix();
            glTranslatef(0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(0.15, 0, 0);
            myArm();  ///右下手臂
        glPopMatrix();
    glPopMatrix();

    glPushMatrix(); ///左半邊
        glTranslatef(-0.3, 0.3, 0);
        glRotatef(angle, 0 ,0 , 1);
        glTranslatef(-0.15, 0, 0);
        myArm();  ///左上手臂
        glPushMatrix();
            glTranslatef(-0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(-0.15, 0, 0);
            myArm();  ///左下手臂
        glPopMatrix();
    glPopMatrix();

    glutSwapBuffers();
}
void motion(int x,int y){
    angle = x;
    glutPostRedisplay();
}
int main(int argc, char*argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-7");
    glutDisplayFunc(display);
    glutMotionFunc(motion);
    glutIdleFunc(display);
    glutMainLoop();
}
8. GLUT程式8
在上一個程式碼中會發現手臂的方向是相互點對稱的,所以試著將左半邊的角度改負號或者右半邊角度改負號,使左邊與右邊是對稱的
#include <GL/glut.h>

void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myBody();

    glPushMatrix(); ///右半邊
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();  ///右上手臂
        glPushMatrix();
            glTranslatef(0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(0.15, 0, 0);
            myArm();  ///右下手臂
        glPopMatrix();
    glPopMatrix();

    glPushMatrix(); ///左半邊
        glTranslatef(-0.3, 0.3, 0);
        glRotatef(-angle, 0 ,0 , 1);
        glTranslatef(-0.15, 0, 0);
        myArm();  ///左上手臂
        glPushMatrix();
            glTranslatef(-0.15, 0, 0);
            glRotatef(-angle, 0 ,0 , 1);
            glTranslatef(-0.15, 0, 0);
            myArm();  ///左下手臂
        glPopMatrix();
    glPopMatrix();

    glutSwapBuffers();
}
void motion(int x,int y){
    angle = x;
    glutPostRedisplay();
}
int main(int argc, char*argv[]){
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-8");
    glutDisplayFunc(display);
    glutMotionFunc(motion);
    glutIdleFunc(display);
    glutMainLoop();
}
9. GLUT程式9:播放音樂
承接上一個程式
a. 在#include 的地方,加入 <mmsystem.h>
b. 在main()的第一行,加入PlaySound("檔案目錄",NULL,SND_ASYNC);
#include <GL/glut.h>
#include <mmsystem.h> ///加上多媒體聲音系統
void myBody(){
    glPushMatrix();
        glColor3f(1,0,0); ///red
        glutWireCube(0.6);
    glPopMatrix();
}
void myArm(){
    glPushMatrix();
        glColor3f(0,1,0); ///green
        glScalef(1,0.4,0.4);
        glutWireCube(0.3);
    glPopMatrix();
}
float angle=0;
void display(){
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    myBody();

    glPushMatrix(); ///右半邊
        glTranslatef(0.3, 0.3, 0);
        glRotatef(angle, 0 ,0 , 1);
        glTranslatef(0.15, 0, 0);
        myArm();  ///右上手臂
        glPushMatrix();
            glTranslatef(0.15, 0, 0);
            glRotatef(angle, 0 ,0 , 1);
            glTranslatef(0.15, 0, 0);
            myArm();  ///右下手臂
        glPopMatrix();
    glPopMatrix();

    glPushMatrix(); ///左半邊
        glTranslatef(-0.3, 0.3, 0);
        glRotatef(-angle, 0 ,0 , 1);
        glTranslatef(-0.15, 0, 0);
        myArm();  ///左上手臂
        glPushMatrix();
            glTranslatef(-0.15, 0, 0);
            glRotatef(-angle, 0 ,0 , 1);
            glTranslatef(-0.15, 0, 0);
            myArm();  ///左下手臂
        glPopMatrix();
    glPopMatrix();

glutSwapBuffers();
}
void motion(int x,int y){
    angle = x;
    glutPostRedisplay();
}
int main(int argc, char*argv[]){
    PlaySound("C:/horse.wav",NULL,SND_ASYNC);
    glutInit(&argc, argv);
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_DEPTH);
    glutCreateWindow("week10-9");
    glutDisplayFunc(display);
    glutMotionFunc(motion);
    glutIdleFunc(display);
    glutMainLoop();
}

I'm burning, but my heart is on the wire.
Don't need a thousand guards to lock me in.
Doesn't take a fool to start a fire.
Solitary spark and wars begin.

You say it's only words
And that it will get easier with time.
Nothing's only words
That's how hearts get hurt.
----Hurts , MIKA

沒有留言:

張貼留言