• 締切済み

3DCG上の動きについて

物を表示させてx軸・y軸・z軸について回転、物を拡大させたり、 縮小させたりする事は出来ます。 どこをどのようにすれば、物を縦や横に動かす事が出来るのか教えて下さい。 下に自分でやってみたプログラムを書いておきます。 光の強さ、main関数等の所は、スペース上、省略してあります。 void light_enable(){ glenable(GL_LIGHTING); glenable(GL_LIGHT0); glenable(GL_DEPTH_TEST); } void set_light(void){ light_enable(); glMaterialfv(GL_FRONT,GL_SPECULAR,lite_spec); glMaterialfv(GL_FRONT,GL_SHININESS,lite_shine); glLightfv(GL_LIGHT0,GL_POSITION,lite_post); } int anime(){ int i,move; for(i=0;i>=10;i++){ if(i==10){ for(i=10;i<0;i--){ move+=move; } } } return 0; } void modeldraw(void){ glpushmatrix(); gclearbuffers(); gltranslated(1.0,1.0,1.0); glrotatef((float)rot_x,1.0,0.0,0.0); glrotatef((float)rot_y,0.0,1.0,0.0); glrotatef((float)rot_z,0.0,0.0,1.0); glMaterialfv(GL_FRONT,GL_DIFFUSE,obj_diffuse1); glMaterialfv(GL_FRONT,GL_AMBIENT,obj_ambient1); glMaterialfv(GL_FRONT,GL_SPECULAR,obj_specular1); glMaterialfv(GL_FRONT,GL_SHININESS,obj_shininess); glscaled(sscale*0.3,sscale*0.3,sscale*0.3); glutSolidSphere(1.0,40,50); glpopmatrix(); glutswapbuffers(); glflush(); } void key_press(unsigned char key, int xk, int yk){ if(key=='x')rot_x=(rot_x+5)%360; else if(key=='y')rot_y=(rot_y+5)%360; else if(key=='z')rot_z=(rot_z+5)%360; else if(key=='S')sscale=sscale*1.2; else if(key=='s')sscale=sscale/1.2; else if(key=='a')anime(); modeldraw(); }

みんなの回答

  • terra5
  • ベストアンサー率34% (574/1662)
回答No.2

>例えば、最初は原点に表示されていて、キーボードのkeyを押して物体が動き始め >一定の条件を満たしたら止まるというような事です。 >このプログラムの場合、右に移動して、一定の時間が経ったら逆に動くというような事をやりたいのです。 このソースだけではよくわかりませんが、 そのためには、一定の時間がたつと呼ばれる関数が必要です。 例えば,1/10秒毎に呼ばれる関数を用意して,そこでx座標を少しづつ足しながら画面を書き換えるという動作をすれば、 x軸方向に移動することになります。 一定の時間で動きを逆にしたいなら、内部にカウンタを用意し,一定の値になったら、足さずに引けば逆方向に動くようになります。 キーが押されるまで動かさないようにするなら、キーが押されるまでは0を足し, キーが押された値を設定すればいいわけです。 って、こういう話なら3DCGは関係ないですね。 単に、移動させるための座表計算をどうすればいいかという話ですから。 もし、これも意味が違うなら、私には質問が理解できないということですので、 引っ込みます。

yukki-asimo
質問者

お礼

アドバイス、有難うございます。 参考になります。

全文を見る
すると、全ての回答が全文表示されます。
  • terra5
  • ベストアンサー率34% (574/1662)
回答No.1

物体の位置を変えるという意味では, glTransrate()でしょうね。 例えば,x,yの位置に表示したいなら、 glpushmatrix(); gltranslated(x,y,0.0); // 現在の描画部 glpopmatrix(); でいいと思いますが。 未確認です(^^: あと、質問のタイトルは3DCGとせずに、OpenGLとした方がいいですよ。

yukki-asimo
質問者

補足

>物体の位置を変えるという意味では, >glTransrate()でしょうね。 私が言いたかった事は、物体の位置を移動させるということです。 例えば、最初は原点に表示されていて、キーボードのkeyを押して物体が動き始め 一定の条件を満たしたら止まるというような事です。 このプログラムの場合、右に移動して、一定の時間が経ったら逆に動くというような事をやりたいのです。 私の質問の言い方が良くなかった事をお詫びします。 お忙しい中、回答をして頂き、どうも有難うございました。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 内定をもらった会社から課題がだされてしまいました。

    正直まったくもってソースコードをいじった事がありません。なのでわかる方いたらぜひ回答お願いします。 ロボットアームが自動的に動くようにしたいんですけどそのソースコードがわからなくてわかるかたいたら教えてください。 #include <stdlib.h> #include <math.h> #include <GL/glut.h> /* * 直方体を描く */ static void myBox(double x, double y, double z) { GLdouble vertex[][3] = { { -x, -y, -z }, { x, -y, -z }, { x, y, -z }, { -x, y, -z }, { -x, -y, z }, { x, -y, z }, { x, y, z }, { -x, y, z } }; const static int face[][4] = { { 0, 1, 2, 3 }, { 1, 5, 6, 2 }, { 5, 4, 7, 6 }, { 4, 0, 3, 7 }, { 4, 5, 1, 0 }, { 3, 2, 6, 7 } }; const static GLdouble normal[][3] = { { 0.0, 0.0,-1.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0 }, {-1.0, 0.0, 0.0 }, { 0.0,-1.0, 0.0 }, { 0.0, 1.0, 0.0 } }; const static GLfloat red[] = { 0.8, 0.2, 0.2, 1.0 }; int i, j; /* 材質を設定する */ glMaterialfv(GL_FRONT, GL_DIFFUSE, red); glBegin(GL_QUADS); for (j = 0; j < 6; ++j) { glNormal3dv(normal[j]); for (i = 4; --i >= 0;) { glVertex3dv(vertex[face[j][i]]); } } glEnd(); } /* * 円柱を描く */ static void myCylinder(double radius, double height, int sides) { const static GLfloat yellow[] = { 0.8, 0.8, 0.2, 1.0 }; double step = 6.28318530717958647692 / (double)sides; int i = 0; /* 材質を設定する */ glMaterialfv(GL_FRONT, GL_DIFFUSE, yellow); /* 上面 */ glNormal3d(0.0, 1.0, 0.0); glBegin(GL_TRIANGLE_FAN); while (i < sides) { double t = step * (double)i++; glVertex3d(radius * sin(t), height, radius * cos(t)); } glEnd(); /* 底面 */ glNormal3d(0.0, -1.0, 0.0); glBegin(GL_TRIANGLE_FAN); while (--i >= 0) { double t = step * (double)i; glVertex3d(radius * sin(t), -height, radius * cos(t)); } glEnd(); /* 側面 */ glBegin(GL_QUAD_STRIP); while (i <= sides) { double t = step * (double)i++; double x = sin(t); double z = cos(t); glNormal3d(x, 0.0, z); glVertex3f(radius * x, height, radius * z); glVertex3f(radius * x, -height, radius * z); } glEnd(); } /* * 地面を描く */ static void myGround(double height) { const static GLfloat ground[][4] = { { 0.6, 0.6, 0.6, 1.0 }, { 0.3, 0.3, 0.3, 1.0 } }; int i, j; glBegin(GL_QUADS); glNormal3d(0.0, 1.0, 0.0); for (j = -5; j < 5; ++j) { for (i = -5; i < 5; ++i) { glMaterialfv(GL_FRONT, GL_DIFFUSE, ground[(i + j) & 1]); glVertex3d((GLdouble)i, height, (GLdouble)j); glVertex3d((GLdouble)i, height, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), height, (GLdouble)(j + 1)); glVertex3d((GLdouble)(i + 1), height, (GLdouble)j); } } glEnd(); } /* * 画面表示 */ static void display(void) { const static GLfloat blue[] = { 0.2, 0.2, 0.8, 1.0 }; /* 球の色 */ const static GLfloat lightpos[] = { 3.0, 4.0, 5.0, 1.0 }; /* 光源の位置 */ /* 画面クリア */ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /* モデルビュー変換行列の初期化 */ glLoadIdentity(); /* 光源の位置を設定 */ glLightfv(GL_LIGHT0, GL_POSITION, lightpos); /* 視点の移動(シーンの方を奥に移す)*/ glTranslated(0.0, 0.0, -10.0); /* シーンの描画 */ myGround(-2.0); /* 地面    */ glTranslated(0.0, -1.8, 0.0); myCylinder(1.0, 0.2, 16); /* 土台    */ glTranslated(0.0, 1.0, 0.0); myBox(0.3, 1.0, 0.3); /* 1番目の腕 */ glTranslated(0.0, 1.0, 0.0); glRotated(90.0, 1.0, 0.0, 0.0); myCylinder(0.4, 0.4, 16); /* 関節    */ glTranslated(0.0, 0.0, -1.0); myBox(0.3, 0.3, 1.0); /* 2番目の腕 */ glTranslated(0.0, 0.0, -1.0); glMaterialfv(GL_FRONT, GL_DIFFUSE, blue); glutSolidCube(0.9); /* ハンド   */ glFlush(); } static void resize(int w, int h) { /* ウィンドウ全体をビューポートにする */ glViewport(0, 0, w, h); /* 透視変換行列の指定 */ glMatrixMode(GL_PROJECTION); /* 透視変換行列の初期化 */ glLoadIdentity(); gluPerspective(30.0, (double)w / (double)h, 1.0, 100.0); /* モデルビュー変換行列の指定 */ glMatrixMode(GL_MODELVIEW); } static void keyboard(unsigned char key, int x, int y) { /* ESC か q をタイプしたら終了 */ if (key == '\033' || key == 'q') {

  • c 言語 B tree

    C言語で B-treeを実装するプログラムを書きました。 まだtreeに挿入する関数しか書いておりませんが。。 まず空の根を作ってからそこにどんどん要素を挿入していくのですが、どうも要素が 挿入されていないように思えます。 どこがいけないのか分かる方いらっしゃいませんか? よろしくお願いします。 #include <stdio.h> #define T 10 struct b_tree{ int key[2*T-1]; struct b_tree *node[2*T]; int size; int leaf;//この節点が葉であったら1とする }; void BTreeCreate(void); void BTreeSplitChild(struct b_tree x,int i,struct b_tree y); void BTreeInsert(struct b_tree t,int k); void BTreeInsertNonfull(struct b_tree x,int k); void PrintBtree(struct b_tree x); struct b_tree root; int main (int argc, const char * argv[]) { // insert code here... /*int t;*/ char command; int key; BTreeCreate(); /*scanf("%d",&t);*/ while (1) { scanf("%c %d",&command,&key); if (command=='E') break; if(command=='I') BTreeInsert(root,key);//木にkeyを挿入 } PrintBtree(root); //木を表示 return 0; } void BTreeCreate(void){//空のB-木の生成 struct b_tree x; x.leaf=1; x.size=0; root=x; } void BTreeSplitChild(struct b_tree x,int i,struct b_tree y){ /*B-木における節点の分割をする節点xのi番目の枝の先にある節点yが飽和であった 場合にyをyの中央値で分ける。yの中央値はxの新たなkeyとなりxの枝数は1つ増える*/ int j; struct b_tree z; z.leaf=y.leaf; //zが葉であるかどうかはyが葉であるかどうかに依る z.size=T-1; //また新しくできるxの子zは最小数のkey(T-1)を持たせる for (j=1; j<= T-1; j++) { z.key[j]=y.key[j+1]; //yの中央値よりおおきい値(T-1個)をzに渡す } if(y.leaf==0){ //またyが個をもつ場合は枝もzに渡す for (j=1; j<=T; j++) z.node[j]=y.node[T+j]; } y.size=T-1; //そしてyのサイズも中央値とzに渡した分小さくなる for (j= x.size+1; j>=i+1; j--) { //xにyの中央値を渡すのでx枝の右半分を1つずつ右へずらす x.node[j+1]=x.node[j]; } x.node[i+1]=&z; //i+1番目の枝に新たな子zのポインタを与える for (j=x.size; j>=i; j--) { //値も右へずらす x.key[j+1]=x.key[j]; } x.key[i]=y.key[T]; //xのi番目の値をyの中央値とする。 x.size=x.size+1; //xは1サイズup } void BTreeInsert(struct b_tree t,int k){ int Tsub=T; //条件部にTが使えなかったのでTsubに退避 struct b_tree r,s; r=t; if (r.size == Tsub) { /*根が飽和だった場合を考える新たな親を必要とするため それをsとする。するとsは葉ではなく、sizeは0, そして元々の根rのポインタを与える*/ s.leaf=0; s.size=0; s.node[1]=&r; root=s; BTreeSplitChild(s,1,r); BTreeInsertNonfull(r,k); } else { BTreeInsertNonfull(r,k); } } void BTreeInsertNonfull(struct b_tree x,int k){ /*未飽和の節点xにkを挿入しようと考える。*/ int i; int Tsub=T; if (x.leaf==1) { /*もし、xが葉であれば大小関係を考えて挿入。その際他のkey を右へ1つずつずらす。またxのサイズを1up*/ while (i>=1 && k<x.key[i]) { x.key[i+1]=x.key[i]; i--; } x.key[i+1]=k; x.size++; } else { /*もしxが葉でなければどこの枝をたどればいいのか考える*/ while (i>=1 && k<x.key[i]) { i--; } i++; if ((*x.node[i]).size == 2*Tsub-1) { /*たどる枝の先が飽和であった場合分割する*/ BTreeSplitChild(x, i, *x.node[i]); if (k > x.key[i]) { i++; } } BTreeInsertNonfull(*x.node[i],k);//枝をたどる } } void PrintBtree(struct b_tree x){ printf("abc"); printf("%d",x.leaf);//実行するとleafが1のままなので、数が挿入されていない? int i,l;        if(x.leaf==1){ for (i=1; i<=x.size; i++) { printf("%d def",x.key[i]); } if(l==0)printf("\n"); }else { for (i=1; i<=x.size; i++) { printf("%d ghi",x.key[i]); } if(l==0)printf("\n"); l++; printf(" jkl"); for (i=1; i <= x.size+1; i++) { PrintBtree(*x.node[i]); } } printf("\n"); }

  • C言語のプログラムについて

    三角形を判定するプログラムを作ったのですが直角三角形ができるはずがないのに直角三角形の判定が出てしまいます。簡単なことなのかもしれませんが自分ではわからなくなってしまったのでご指摘してもらいたいです。 #include<stdio.h> void tri(int x,int y,int z) { if((x*x==y*y+z*z)||(y*y==x*x+z*z)||(z*z==x*x+y*y)) { printf("これは直角三角形です。"); printf("これは三角形です。"); }else if((x+y>=z)||(x+z>=y)||(y+z>=x)) { printf("これは三角形ではありません。"); }else{ printf("これは三角形です。"); } } int main(void) { int e1,e2,e3; printf("3辺を入力してください"); scanf("%f,%f,%f",&e1,&e2,&e3); tri(e1,e2,e3); return(0); }

  • C言語の問題がわからないです。

    C言語のプログラムで、列数を自分で決めて、 (例)3列         ●(この行を最後として)   □● ●□● 上記のプログラムを作りたいのですが、 上手くいきません。途中まで作ったのですが、なかなか思うようにいかないです。どうすれば上記のようになりますでしょうか? #include <stdio.h> void disp(int x, int y); main() { int i,n; printf("表示する列:"); scanf("%d",&n); disp(3,3); for(i=1;i<=n;i++){ if(i%2==0){ disp(n-i,4); disp(i,2); } else{ disp(n-i,4); disp(i,1); } disp(1,3); } } void disp(int x, int y) { int i; for(i=0;i<x;i++){ if(y==1){ printf("●"); } else if(y==2){ printf("□"); } else if(y==3){ printf("\n"); } else{ printf("\0"); } } }

  • 線形補間

    線形補間での求め方 問題文: 1.数値を読み込む 2.xを読み込む 3.x<x1 または x>xnならエラー 3.x1<x<i+1 となるiを見つける 4.補間公式でyを求める 5.結果をプリントする #include<stdio.h> float hokan(void); int xn[] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75}; double yn[] = {0.000,0.087,0.173,0.258,0.342,0.422,0.500,0.573, 0.624,0.707,0.766,0.819,0.866,0.906,0.939,0.965}; int x=5; void main() { printf("y = %lf\n", hokan()); } float hokan(void) { int i; double y; if(x <0|| 75<= x){ printf("エラーです\n"); } else{ for(i=0; xn[i] < x; i++) y = (yn[i+1] - yn[i]) * (x - xn[i]) / (xn[i+1] - xn[i]) + yn[i]; return y; } } 数表を最初にxnとynで表記しています。 このプログラムで線形補間が行われてないそうなのですが・・ 何か誤りがある様でしたらどなたか教えてください。

  • mの平方根の連分数展開なのですがうまく動きません。

    subroutine keisan(m) integer a,a0,n,i,m real t,X,Y,Z t=sqrt(real(m)) a0=int(t) write(*,*) 'a0=',a0 a=a0 X=1 Y=0 Z=1 do 10 n=1,20 if (Z==0.0) exit X=X*Z Y=Z*(-Y+real(a)*Z) Z=X*X*real(m)-(real(a)*Z-Y)**2 do 100 i=1,X if(real(i)==X) then X=X else if(((mod(int(X),i))==0).AND.((mod(int(Y),i))==0).AND.((mod(int(Z),i))==0)) then X=X/real(i) Y=Y/real(i) Z=Z/real(i) else X=X endif endif 100 continue a=int((X*t+Y)/Z) write(*,*) 'a',n,'=',a 10 continue end subroutine サブルーチンのみ載せてますけど・・・・どうなのでしょう??

  • 再帰呼び出し

    アッカーマン関数の値を出力するプログラム #include void main(void); int ack(int,int); void main(void) { int x,y,i; printf(" data(x) = "); scanf("%d",&x); printf(" data(y) = "); scanf("%d",&y); i = ack(x,y); printf("Ackerman = %d\n",i); } int ack(int a,int b) { int k; if (a == 0) k = b+1; else if (b == 0) k = ack(a-1,1); else k = ack(a-1,ack(a,b-1)); return (k); } この関数を呼び出した回数も出力するようにしたいのですが、どうしたらいいのでしょうか?

  • synchronizedによる同期化について

    Javaで開発しています。 synchronizedで同期化したく、サンプルを作ってみたのですが上手く同期化が出来ていないようなので質問しました。 以下プログラム public class Synch{ public static void main(String[] args){ final Something obj = new Something(); new Thread(){ public void run(){ synchronized(this){ try{ obj.write(); } catch(Exception e){ }notify();} } }.start(); new Thread(){ public void run(){ try{ obj.read(); } catch(Exception e){ } } }.start(); } } class Something{ private int x = 10; private int y = 100; public synchronized void write(){ if(x < y){ System.out.println("write:x < y"); } else if(x > y){ System.out.println("write:x > y"); } for(int n = 0;n < 100;n++){ x++; y++; } for(int m = 0;m < 150;m++){ y--; } if(x < y){ System.out.println("write:x < y"); } else if(x > y){ System.out.println("write:x > y"); } } public synchronized void read(){ if(x < y){ System.out.println("read:x < y"); } else if(x > y){ System.out.println("read:x > y"); } } } このプログラムを実行すると、時々readのほうが先に表示されてしまいます。 実行環境はEclipse2.1.3です。 readが先に表示されるのは仕方のないことなのでしょうか? それともプログラムがいけないのでしょうか? ご存知の方いらっしゃいましたら教えて頂けないでしょうか。 不足がありましたら仰ってください。

    • ベストアンサー
    • Java
  • コードの最適化について質問です。以下の2つのコードにおいて、最適化が可能なポイントを教えていただけませんか?

    *gccコンパイラを通します。 ///code1/// void filter_optimized(int width, int height, int numcol, int rw, int gw, int bw) { int x, y, z; for (z=0; z<numcol; z++) for (x=0; x<height; x++) for (y=0; y<width; y++) if (z==0) c[x][y][z] = bw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); else if(z==1) c[x][y][z] = gw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); else c[x][y][z] = rw*((bw*a[x][y][0]+gw*a[x][y][1]+rw*a[x][y][2])/(rw+gw+bw)); return; } ///code2/// void edge_optimized(int width, int height, int numcol) { int x, y, z; int tmp; for (y = 0; y < width; y++) for (x = 0; x < height; x++) for (z = 0; z < numcol; z++) b[x][y][z] = (a[x][y][0]+a[x][y][1]+a[x][y][2])/3; for (y = 0; y < width; y++) for (x = 0; x < height; x++) for (z = 0; z < numcol; z++) { tmp = computeGx(width, height, x, y, z, b); if (tmp < 0) tmp = -tmp; if (tmp > 255) tmp = 255; c[x][y][z] = tmp; tmp = computeGy(width, height, x, y, z, b); if (tmp < 0) tmp = -tmp; if (tmp + c[x][y][z] > 255) c[x][y][z] = 255; else c[x][y][z] += tmp; c[x][y][z] = 255 - c[x][y][z]; if ((x==0)||(y==0)||(x==height-1)||(y==width-1)) c[x][y][z] = 255; } return; }

  • 参照による呼び出し

    参照による呼び出しで3つの整数を大きい順に並び替えるという プログラムで、 #include<stdio.h> void change(int *x,int *y,int *z);/       main(){ int a,b,c; scanf("%d %d %d",&a,&b,&c); printf("入力データ:a=%d,b=%d,c=%d\n",a,b,c); change(&a,&b,&c); printf("入れ替え後:a=%d,b=%d,c=%d\n",a,b,c); return(0); } void change(int *x,int *y,int *z){ if(*x>*y){ *a=*x; *c=*y; } else{ *a=*y; *c=*x; } if(*z>*a){ *b=*a; *a=*z; } else if(*z>*c){ *b=*z; } else{ *b=*c; *c=*z; } } のように作ったのですが、zの値が一度も使われていないとエラーが 出てしまいます。どこをどう直せばいいか教えてください。 お願いします。

文字入力の字を大きくしたい
このQ&Aのポイント
  • LINEでの文字入力の時、文字のサイズを大きくしたいのですがどうしたらいいか教えて欲しい。
  • らくらくフォンF-03Kの文字入力の字を大きくする方法を教えてください。
  • 富士通FMVの文字入力時のフォントサイズを調整する方法を教えてください。
回答を見る