本周也是基於上星期的程式碼做修改,我們會做大量的修改,我們先新增一個int變數angleID 然後在一個新的函數keyboard函數設定angleID,然後用timer計算angleID,並在main函式中增加keyboard的函式,這樣就可以用鍵盤上的按鍵操作茶壺手臂
///新專案,刪光光,放入上周的程式,改成week16,把float angle改成 float angle[20]
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={},diff=2;///上週程式,會增加、會減少!!!,都是0的陣列 angle
int angleID=0;///現在有20個angle,利用angle[0],angle[1]...angle[angleID]
void timer(int t)///上週程式,會增加、會減少!!!
{
glutTimerFunc( 30, timer, t+1 );///上週程式 設定新的timer
angle[angleID] += diff;///上週程式,會增加、會減少!!!
if(angle[angleID]>90) diff = -2;///上週程式,會增加、會減少!!!
if(angle[angleID]<0) diff = +2;///上週程式,會增加、會減少!!!
glutPostRedisplay();///上週教display();
}
void keyboard(unsigned char key,int x,int y){///keyboard()需要glutKeyboard
if(key=='0') angleID=0;/// 之後timer()會改變關節angle[0]
if(key=='1') angleID=1;/// 之後timer()會改變關節angle[1]
if(key=='2') angleID=2;/// 之後timer()會改變關節angle[2]
if(key=='3') angleID=3;/// 之後timer()會改變關節angle[3]
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();///Step05-2
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///Step05-2
glTranslatef(-0.3,0,0);
glRotatef(angle[0], 0,0,1);
glTranslatef(-0.3,0,0);
glutSolidTeapot( 0.3 );///左手臂, 但是,要用 T-R-T移位置
glPushMatrix();
glTranslatef(-0.3, 0,0);
glRotatef(angle[1], 0,0,1);
glTranslatef(-0.3, 0,0);
glutSolidTeapot( 0.3 );///左手肘
glPopMatrix();
glPopMatrix();///Step05-2
glPushMatrix();///Step05-2
glTranslatef(+0.3,0,0);
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();///step05-3
glTranslatef(+0.3,0,0);
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();///Step05-3
glPopMatrix();///Step05-2
glPopMatrix();///Step05-2
glutSwapBuffers();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow( "week16 many angles" );
glutKeyboardFunc(keyboard);
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0);
glutMainLoop();
}///先不放貼圖, 先不放打光
因為timer動起來很規律,我們想要讓timer不要那麼規律,可以用滑鼠自由活動,所以我們讓timer什麼都不做,改用滑鼠操作,新增幾個變數x,y還有紀錄就的x,y
像這樣,可以用滑鼠自由移動各種角度,然後用鍵盤上的數字鍵來選擇你所要操作的關節,這樣的話就可以做到關節的自由移動
程式碼:
///新專案,刪光光,放入上周的程式,改成week16,把float angle改成 float angle[20]
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={},diff=2;///上週程式,會增加、會減少!!!,都是0的陣列 angle
int angleID=0;///現在有20個angle,利用angle[0],angle[1]...angle[angleID]
/*void timer(int t)///上週程式,會增加、會減少!!!
{
glutTimerFunc( 30, timer, t+1 );///上週程式 設定新的timer
angle[angleID] += diff;///上週程式,會增加、會減少!!!
if(angle[angleID]>90) diff = -2;///上週程式,會增加、會減少!!!
if(angle[angleID]<0) diff = +2;///上週程式,會增加、會減少!!!
glutPostRedisplay();///上週教display();
}*/
int oldX=0,oldY=0;
void mouse(int button,int state, int x,int y){
///mouse按下去時,記下現在的位置
oldX = x;
oldY = y;
}
void motion(int x,int y){
///mouse motion時,會叫這個motion()
angle[angleID] += x - oldX;
oldX = x;
glutPostRedisplay();///上週教display
}
void keyboard(unsigned char key,int x,int y){///keyboard()需要glutKeyboard
if(key=='0') angleID=0;/// 之後timer()會改變關節angle[0]
if(key=='1') angleID=1;/// 之後timer()會改變關節angle[1]
if(key=='2') angleID=2;/// 之後timer()會改變關節angle[2]
if(key=='3') angleID=3;/// 之後timer()會改變關節angle[3]
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();///Step05-2
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///Step05-2
glTranslatef(-0.3,0,0);
glRotatef(angle[0], 0,0,1);
glTranslatef(-0.3,0,0);
glutSolidTeapot( 0.3 );///左手臂, 但是,要用 T-R-T移位置
glPushMatrix();
glTranslatef(-0.3, 0,0);
glRotatef(angle[1], 0,0,1);
glTranslatef(-0.3, 0,0);
glutSolidTeapot( 0.3 );///左手肘
glPopMatrix();
glPopMatrix();///Step05-2
glPushMatrix();///Step05-2
glTranslatef(+0.3,0,0);
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();///step05-3
glTranslatef(+0.3,0,0);
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();///Step05-3
glPopMatrix();///Step05-2
glPopMatrix();///Step05-2
glutSwapBuffers();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow( "week16 many angles" );
glutKeyboardFunc(keyboard);
glutDisplayFunc( display );
glutTimerFunc( 0, timer, 0);
glutMainLoop();
}///先不放貼圖, 先不放打光
接下來我們要把旋轉的角度給存起來,利用上禮拜教到的fopen,fprintf可以把東西給存起來,然後用for迴圈就可以把所有角度都同時印出來。如果指標為空指標就fopen
///新專案,刪光光,放入上周的程式,改成week16,把float angle改成 float angle[20]
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={},diff=2;///上週程式,會增加、會減少!!!,都是0的陣列 angle
int angleID=0;///現在有20個angle,利用angle[0],angle[1]...angle[angleID]
/*void timer(int t)///上週程式,會增加、會減少!!!
{
glutTimerFunc( 30, timer, t+1 );///上週程式 設定新的timer
angle[angleID] += diff;///上週程式,會增加、會減少!!!
if(angle[angleID]>90) diff = -2;///上週程式,會增加、會減少!!!
if(angle[angleID]<0) diff = +2;///上週程式,會增加、會減少!!!
glutPostRedisplay();///上週教display();
}*/
int oldX=0,oldY=0;
void mouse(int button,int state, int x,int y){
///mouse按下去時,記下現在的位置
oldX = x;
oldY = y;
}
void motion(int x,int y){
///mouse motion時,會叫這個motion()
angle[angleID] += x - oldX;
oldX = x;
glutPostRedisplay();///上週教display
}
#include <stdio.h>///上週教的第0步 才能用fopen() printf fprintf()
FILE * fout = NULL;///上週教的第一步
void keyboard(unsigned char key,int x,int y){///keyboard()需要glutKeyboard
if(key=='0') angleID=0;/// 之後timer()會改變關節angle[0]
if(key=='1') angleID=1;/// 之後timer()會改變關節angle[1]
if(key=='2') angleID=2;/// 之後timer()會改變關節angle[2]
if(key=='3') angleID=3;/// 之後timer()會改變關節angle[3]
if(key=='s'){///想要存檔Save
if(fout == NULL)fout = fopen("angle.txt","w+");///step03若NULL,fopen()
for(int i=0;i<20;i++) printf("%.2f ",angle[i]);///step03 for迴圈印陣列
printf("\n");
for(int i=0;i<20;i++) fprintf(fout,"%.2f ",angle[i]);///step03 for迴圈印陣列
fprintf(fout,"\n");
}
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();///Step05-2
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///Step05-2
glTranslatef(-0.3,0,0);
glRotatef(angle[0], 0,0,1);
glTranslatef(-0.3,0,0);
glutSolidTeapot( 0.3 );///左手臂, 但是,要用 T-R-T移位置
glPushMatrix();
glTranslatef(-0.3, 0,0);
glRotatef(angle[1], 0,0,1);
glTranslatef(-0.3, 0,0);
glutSolidTeapot( 0.3 );///左手肘
glPopMatrix();
glPopMatrix();///Step05-2
glPushMatrix();///Step05-2
glTranslatef(+0.3,0,0);
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();///step05-3
glTranslatef(+0.3,0,0);
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();///Step05-3
glPopMatrix();///Step05-2
glPopMatrix();///Step05-2
glutSwapBuffers();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow( "week16 many angles" );
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc( display );
/// glutTimerFunc( 0, timer, 0);
glutMainLoop();
}///先不放貼圖, 先不放打光
再來我們把在keyboard裡的其中五行程式碼複製到motion裡面,並將#include <stdio.h>及其下面兩行程式碼移動到motion上面,並將angle.txt和freeglut.dll移動到本周的資料夾當中,然後記得將工作目錄都改成小數點就可以透過存讀檔案的方式來讓手臂進行移動。
程式碼:
///新專案,刪光光,放入上周的程式,改成week16,把float angle改成 float angle[20]
#include <stdio.h>
#include <GL/glut.h>
float angle[20]={},diff=2;///上週程式,會增加、會減少!!!,都是0的陣列 angle
int angleID=0;///現在有20個angle,利用angle[0],angle[1]...angle[angleID]
/*void timer(int t)///上週程式,會增加、會減少!!!
{
glutTimerFunc( 30, timer, t+1 );///上週程式 設定新的timer
angle[angleID] += diff;///上週程式,會增加、會減少!!!
if(angle[angleID]>90) diff = -2;///上週程式,會增加、會減少!!!
if(angle[angleID]<0) diff = +2;///上週程式,會增加、會減少!!!
glutPostRedisplay();///上週教display();
}*/
int oldX=0,oldY=0;
void mouse(int button,int state, int x,int y){
///mouse按下去時,記下現在的位置
oldX = x;
oldY = y;
}
#include <stdio.h>///上週教的第0步 才能用fopen() printf fprintf()
FILE * fout = NULL;///上週教的第一步
FILE * fin = NULL;///step04 準備讀黨的 fin input 用
void motion(int x,int y){
///mouse motion時,會叫這個motion()
angle[angleID] += x - oldX;
oldX = x;
glutPostRedisplay();///上週教display
if(fout == NULL)fout = fopen("angle.txt","w+");///step03若NULL,fopen()
for(int i=0;i<20;i++) printf("%.2f ",angle[i]);///step03 for迴圈印陣列
printf("\n");
for(int i=0;i<20;i++) fprintf(fout,"%.2f ",angle[i]);///step03 for迴圈印陣列
fprintf(fout,"\n");
}
void keyboard(unsigned char key,int x,int y){///keyboard()需要glutKeyboard
if(key=='0') angleID=0;/// 之後timer()會改變關節angle[0]
if(key=='1') angleID=1;/// 之後timer()會改變關節angle[1]
if(key=='2') angleID=2;/// 之後timer()會改變關節angle[2]
if(key=='3') angleID=3;/// 之後timer()會改變關節angle[3]
if(key=='s'){///想要存檔Save
if(fout == NULL)fout = fopen("angle.txt","w+");///step03若NULL,fopen()
for(int i=0;i<20;i++) printf("%.2f ",angle[i]);///step03 for迴圈印陣列
printf("\n");
for(int i=0;i<20;i++) fprintf(fout,"%.2f ",angle[i]);///step03 for迴圈印陣列
fprintf(fout,"\n");
}///你必須fclose(fout) 或程式關閉後 ,才會更新硬碟裡的 angle.txt
if(key=='r'){///step04:想讀進來
if(fin == NULL )fin = fopen("angle.txt","r");
for(int i=0; i<20; i++) fscanf(fin, "%f" , &angle[i]);
glutPostRedisplay();///step04重劃畫面
}
}
void display()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glPushMatrix();///Step05-2
glutSolidTeapot( 0.3 );///身體
glPushMatrix();///Step05-2
glTranslatef(-0.3,0,0);
glRotatef(angle[0], 0,0,1);
glTranslatef(-0.3,0,0);
glutSolidTeapot( 0.3 );///左手臂, 但是,要用 T-R-T移位置
glPushMatrix();
glTranslatef(-0.3, 0,0);
glRotatef(angle[1], 0,0,1);
glTranslatef(-0.3, 0,0);
glutSolidTeapot( 0.3 );///左手肘
glPopMatrix();
glPopMatrix();///Step05-2
glPushMatrix();///Step05-2
glTranslatef(+0.3,0,0);
glRotatef(-angle[2], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手臂
glPushMatrix();///step05-3
glTranslatef(+0.3,0,0);
glRotatef(-angle[3], 0,0,1);
glTranslatef(+0.3,0,0);
glutSolidTeapot( 0.3 );///右手肘
glPopMatrix();///Step05-3
glPopMatrix();///Step05-2
glPopMatrix();///Step05-2
glutSwapBuffers();
}
int main( int argc, char** argv )
{
glutInit( &argc, argv );
glutInitDisplayMode( GLUT_DOUBLE | GLUT_DEPTH );
glutCreateWindow( "week16 many angles" );
glutKeyboardFunc(keyboard);
glutMouseFunc(mouse);
glutMotionFunc(motion);
glutDisplayFunc( display );
/// glutTimerFunc( 0, timer, 0);
glutMainLoop();
}///先不放貼圖, 先不放打光








沒有留言:
張貼留言