2017年6月6日 星期二

Week16_嗯對,這是賴小沫的

 1_Excel 內插公式

用Excel嘗試內插公式
    =A2*newValue+(1-A2)*oldValue
 

 2_存檔

利用上次的作業檔案,用Notepad++開啟cbp專案檔
 
修改working、include、lib的路徑位置

開啟專案檔後,修改讀入模型的路徑

新增能存取各關節角度數據的程式碼

...
#include <stdio.h> //為了存讀檔的fprintf、fscanf
FILE *fout=NULL;  //存檔步驟:宣告一個檔案的指標(一開始是空的)
void keyboard(unsigned char key,int x,int y)
{
    printf("%c\n",key);  //按了什麼鍵,印出來方便看
    if(key=='s'){  //存檔步驟:按下s鍵後存檔
        if(fout==NULL){
            fout=fopen("file.txt","w+");   //開啟檔案,檔名準備好,而且是用write+模式
            printf("Now open a file.txt,w+ Mode\n");
        }
        printf("Write angle[] %f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        fprintf(fout,"%f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        //建立檔案內容
    }
    if(key=='0') now=0;
    if(key=='1') now=1;
    if(key=='2') now=2;
    if(key=='3') now=3;
    if(key=='4') now=4;
    if(key=='5') now=5;
    if(key=='6') now=6;
    if(key=='7') now=7;
    if(key=='8') now=8;
    if(key=='9') now=9;
}
...

按下F9,執行過程中,將模型調整為想要的樣子,並按下s鍵存檔

所有動作都儲存完成後,將執行檔關閉,資料夾會有一個紀錄數據的文件檔
 
 
文件檔內紀錄的角度數據
 

 3_讀檔

撰寫可以讀入下圖文件檔數據的程式碼
 
延續使用剛才的程式碼,並新增一些內容
 
...
FILE *fout=NULL;  //存檔步驟:宣告一個檔案的指標(一開始是空的)
FILE *fin=NULL;  //讀檔步驟:宣告一個檔案的指標(一開始是空的)
void keyboard(unsigned char key,int x,int y)
{
    printf("%c\n",key);  //按了什麼鍵,印出來方便看
    if(key=='s'){  //存檔步驟:按下s鍵後存檔
        if(fout==NULL){
            fout=fopen("file.txt","w+");   //開啟檔案,檔名準備好,而且是用write+模式
            printf("Now open a file.txt,w+ Mode\n");
        }
        printf("Write angle[] %f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        fprintf(fout,"%f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        //建立檔案內容
    }
    if(key=='r'){  //讀檔步驟:按下r鍵後讀檔
        if(fin==NULL){
            fin=fopen("file.txt","r");   //開啟檔案,檔名準備好,而且是用read模式
            printf("Now open a file.txt for read Mode\n");
        }
        fscanf(fin,"%f %f %f %f %f %f %f %f %f %f",&angle[0],&angle[1],
            &angle[2],&angle[3],&angle[4],&angle[5],&angle[6],&angle[7],&angle[8],&angle[9]);
        printf("Now read angle[]\n");
    }
    if(key=='0') now=0;
    if(key=='1') now=1;
    if(key=='2') now=2;
    if(key=='3') now=3;
    if(key=='4') now=4;
    if(key=='5') now=5;
    if(key=='6') now=6;
    if(key=='7') now=7;
    if(key=='8') now=8;
    if(key=='9') now=9;
}
...
 
按下F9執行,過程中只要按r便會讀入每個動作的數據
 

 4_利用內插方式讀檔,讓動作流暢

為了讓動作看起來更加流暢,不會卡卡的,所以使用內插的方式
將剛才的程式碼修改如下:
 

...
float alpha=0.0;  //改用交叉相乘的內插方式算角度
float oldAngle[20]={};
float newAngle[20]={};
float angle[20]={};  //用來畫圖的angle陣列
int now=0;
FILE *fout=NULL;  //存檔步驟:宣告一個檔案的指標(一開始是空的)
FILE *fin=NULL;  //讀檔步驟:宣告一個檔案的指標(一開始是空的)
void keyboard(unsigned char key,int x,int y)
{
    printf("%c\n",key);  //按了什麼鍵,印出來方便看
    if(key=='s'){  //存檔步驟:按下s鍵後存檔
        if(fout==NULL){
            fout=fopen("file.txt","w+");   //開啟檔案,檔名準備好,而且是用write+模式
            printf("Now open a file.txt,w+ Mode\n");
        }
        printf("Write angle[] %f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        fprintf(fout,"%f %f %f %f %f %f %f %f %f %f\n",
            angle[0],angle[1],angle[2],angle[3],angle[4],angle[5],angle[6],angle[7],angle[8],angle[9]);
        //建立檔案內容
    }
    if(key=='r'){  //讀檔步驟:按下r鍵後讀檔
        if(fin==NULL){
            fin=fopen("file.txt","r");   //開啟檔案,檔名準備好,而且是用read模式
            printf("Now open a file.txt for read Mode\n");
            fscanf(fin,"%f %f %f %f %f %f %f %f %f %f",&newAngle[0],&newAngle[1],&newAngle[2],&newAngle[3],&newAngle[4],&newAngle[5],&newAngle[6],&newAngle[7],&newAngle[8],&newAngle[9]
);
        }
        if(alpha>=1.0){
            for(int i=0;i<10;i++) oldAngle[i]=newAngle[i];
            fscanf(fin,"%f %f %f %f %f %f %f %f %f %f",&newAngle[0],&newAngle[1],&newAngle[2],&newAngle[3],&newAngle[4],&newAngle[5],&newAngle[6],&newAngle[7],&newAngle[8],&newAngle[9]
);
            printf("Now read angle[]\n");
            alpha=0.0;
        }
        for(int i=0;i<10;i++){
            angle[i]=alpha*newAngle[i]+(1-alpha)*oldAngle[i];
        }
        alpha+=0.1;
 
        glutPostRedisplay();
    }
    if(key=='0') now=0;
    if(key=='1') now=1;
    if(key=='2') now=2;
    if(key=='3') now=3;
    if(key=='4') now=4;
    if(key=='5') now=5;
    if(key=='6') now=6;
    if(key=='7') now=7;
    if(key=='8') now=8;
    if(key=='9') now=9;
}
...
 
按下F9執行,過程中只要按r便會讀入每個動作的數據,動作看起來也會較流暢

 5_使用Timer播放

延續使用程式碼,新增計時器的函式
 
...
void timer(int t)
{
    glutTimerFunc(100,timer,t+1);
    if(fin==NULL){
        fin=fopen("file.txt","r");   //開啟檔案,檔名準備好,而且是用read模式
        printf("Now open a file.txt for read Mode\n");
        fscanf(fin,"%f %f %f %f %f %f %f %f %f %f",&newAngle[0],&newAngle[1],&newAngle[2],&newAngle[3],&newAngle[4],&newAngle[5],&newAngle[6],&newAngle[7],&newAngle[8],&newAngle[9]
);
    }
    if(alpha>=1.0){
       for(int i=0;i<10;i++) oldAngle[i]=newAngle[i];
       fscanf(fin,"%f %f %f %f %f %f %f %f %f %f",&newAngle[0],&newAngle[1],&newAngle[2],&newAngle[3],&newAngle[4],&newAngle[5],&newAngle[6],&newAngle[7],&newAngle[8],&newAngle[9]
);
       printf("Now read angle[]\n");
       alpha=0.0;
    }
    for(int i=0;i<10;i++){
       angle[i]=alpha*newAngle[i]+(1-alpha)*oldAngle[i];
    }
    alpha+=0.1;
 
    glutPostRedisplay();
}
int main()
{
    ....
    glutTimerFunc(1000,timer,0);
    ....
}
 
按下F9執行,只要計時器開始計時,模型就會自己開始動

沒有留言:

張貼留言