2019年7月27日土曜日
opengl pyopengl ティーポットがデータに従って移動回転
#!/usr/bin/env python
#coding:utf-8
# [2019-07-20]
#@@@
#データを読み取りそれにしたがってティーポット
#データの数値が文字列であつかわれてる
#移動、回転表示
#gluLookAtを使って視点を変えて見たかったけれどなぜか変わらず
#@@@
#参考サイト
#http://www.oit.ac.jp/is/L231/~whashimo/Article/OpenGL/Chapter4
#映像との相互作用
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
import numpy as np
import csv
GRID_SIZE = 100.0
GRID_STEP = 5.0
data_ls = []
index = 0
flg_move = 0
flg_rota = 0
def idle(value):
global index
index += 1
glutPostRedisplay()
#プログラム中でウィンドウの再描画イベントを発生させる
glutTimerFunc(50 , idle , 0)
def init():
global data_ls
#黒で画面クリア
glClearColor(0.0, 0.0, 0.0, 0.0)
glShadeModel(GL_SMOOTH) #フラットシェーディング
glEnable(GL_DEPTH_TEST)
#光源の設定と物体の質感
glEnable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glEnable(GL_COLOR_MATERIAL)
#データファイルオープン
try:
f = open("path.csv", "r")
except:
print"ファイルが読み込めませんでした"
#csv.readerオブジェクトを作成するとforで一行をリストで
#抽出できる
reader = csv.reader(f)
for row in reader:
#以下を実行してわかる通りデータが文字列として扱われてる
#print type(row[0])
data_ls.append(row)
# ファイルをクローズする
f.close()
#resizeはウィンドウリサイズ時と最初に一回実行される
def resize(w,h):
print "resize"
glViewport(0,0,w,h)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
#*glFrustum*
#引数はglOrthoと同じleft,right,top,bttom,znear,zfar
#glFrustum(-5.0, 5.0, -5.0, 5.0, 5.0, 10000.0)
glFrustum(-3.0, 3.0, -3.0, 3.0, 5.0, 10000.0)
#gluPerspective(20.0, w/h, 1.0, 10.0)
#glTranslated(0.0, 0.0, -5.0)
glMatrixMode(GL_MODELVIEW)
glLoadIdentity()
#x-y平面上に格子を表示する
def display_grid():
glBegin(GL_LINES)
for x in np.linspace(-GRID_SIZE/2.0, GRID_SIZE/2.0,
GRID_SIZE/GRID_STEP+1):
glVertex3f(x, GRID_SIZE/2.0, 0.0)
glVertex3f(x, -GRID_SIZE/2.0, 0.0)
glVertex3f(GRID_SIZE/2.0, x, 0.0)
glVertex3f(-GRID_SIZE/2.0, x, 0.0)
glEnd()
#立方体上に格子模様を描く
def display_surrounded_grid():
#立方体のz軸負側にあるx-y面で格子を描く
glPushMatrix()
glColor3f(1.0, 0.0, 0,0)
glTranslatef(0.0, 0.0, -GRID_SIZE/2)
display_grid()
glPopMatrix()
#立方体のz軸正側にあるx-y面で格子を描く
glPushMatrix()
glColor3f(0.0, 0.0, 0,0)
glTranslatef(0.0, 0.0, GRID_SIZE/2)
display_grid()
glPopMatrix()
#立方体のy軸負側にあるx-y面で格子を描く
glColor3f(0.0, 1.0, 0,0)
glPushMatrix()
glTranslatef(0.0, -GRID_SIZE/2, 0.0)
glRotatef(90.0, 1.0, 0.0, 0.0)
display_grid()
glPopMatrix()
#立方体のy軸正側にあるx-y面で格子を描く
glPushMatrix()
glTranslatef(0.0, GRID_SIZE/2, 0.0)
glRotatef(90.0, 1.0, 0.0, 0.0)
display_grid()
glPopMatrix()
#立方体のx軸負側にあるy-z面で格子を描く
glColor3f(0.0, 0.0, 1,0)
glPushMatrix()
glTranslatef(-GRID_SIZE/2, 0.0, 0.0)
glRotatef(90.0, 0.0, 1.0, 0.0)
display_grid()
glPopMatrix()
#立方体のx軸正側にあるy-z面で格子を描く
glPushMatrix()
glTranslatef(GRID_SIZE/2, 0.0, 0.0)
glRotatef(90.0, 0.0, 1.0, 0.0)
display_grid()
glPopMatrix()
def display():
global data_ls
global index
print "display"
"""
元コードは以下のようにしているが、これだとファイルのデータ>
込んですぐ
glTranslatef(pos_x, pos_y, pos_z)
などとしている。
このコードではdisplay関数は多分リサイズ以外一回しか実行され
のでデータを読み込んで軌跡を描く事は不可能では?
fscanf(fp, "%f,%f,%f,%f,%f,%f",
&pos_x, &pos_y, &pos_z, &alpha, &beta, &gamma);
if(feof(fp)){
fclose(fp);
exit(1);
}
.......
glTranslatef(pos_x, pos_y, pos_z)
.......
c言語fscaaf動作確認コード
/media/moto/volume/googledrive/myprg_main/gcc/file_fscanf.c
"""
tx = data_ls[index][0]
ty = data_ls[index][1]
tz = data_ls[index][2]
alpha = data_ls[index][3]
beta = data_ls[index][4]
gamma = data_ls[index][5]
tx = float(tx)
ty = float(ty)
tz = float(tz)
alpha = float(alpha)
beta = float(beta)
gamma = float(gamma)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
glLoadIdentity()
##この行までがワールド座標系
glTranslatef(0.0, 0.0, -200.0)
##格子作成
display_surrounded_grid()
##移動
glTranslatef(tx, ty, tz)
##回転
##*glRotatef*回転 角度は度数法つまり90度とか、ラジアンでは
##キーボードからの回転のコードとはRotaの順が違う
glRotatef(gamma , 0.0, 0.0, 1.0)
glRotatef(beta , 0.0, 1.0, 0.0)
glRotatef(alpha , 0.0, 0.0, 1.0)
##実際に色を塗る関数
glColor3f(1.0, 1.0, 0.0)
##ティーポットの口は元々x軸正方 向に向いているので 視線方向
##)に変換する*
#glRotatef(90.0, 0.0, 1.0, 0.0)
gluLookAt(0.0, 2.5, 1.5, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0)
##引数は多分大きさ?
glutSolidTeapot(10.0)
glFlush()
glutSwapBuffers()
def keyboard(key, x, y):
if key == 'q' or key == 'Q':
# ファイルをクローズする
f.close()
sys.exit()
def special_key(key, x, y):
global tx
global ty
global tz
global alpha
global beta
global gamma
if flg_move == 1:
if key == GLUT_KEY_UP:
ty += 0.4
if key == GLUT_KEY_DOWN:
ty -= 0.4
if key == GLUT_KEY_LEFT:
tx -= 0.4
if key == GLUT_KEY_RIGHT:
tx += 0.4
if key == GLUT_KEY_PAGE_UP:
tz += 0.4
if key == GLUT_KEY_PAGE_DOWN:
tz -= 0.4
if flg_rota == 1:
if key == GLUT_KEY_UP:
alpha += 0.4
if key == GLUT_KEY_DOWN:
alpha -= 0.4
if key == GLUT_KEY_LEFT:
beta -= 0.4
if key == GLUT_KEY_RIGHT:
beta += 0.4
if key == GLUT_KEY_PAGE_UP:
gamma += 0.4
if key == GLUT_KEY_PAGE_DOWN:
gamma -= 0.4
glutPostRedisplay()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
glutInitWindowSize(500, 500)
glutInitWindowPosition(100, 100)
glutCreateWindow("軌跡")
init()
glutDisplayFunc(display)
glutReshapeFunc(resize)
glutTimerFunc(5 , idle , 0)
glutKeyboardFunc(keyboard)
#特殊なキーの入力を受け付ける
#*glutSpecialFunc*
glutSpecialFunc(special_key)
glutMainLoop()
if __name__ == "__main__":
main()
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿