描画した図形を操作する(4)
PythonのOpenGLライブラリで、図形の描画を行う練習をしている。とりあえずは、以下のプロセスに沿って、いろいろと機能を試して練習を進めていく。最初は描画した図形をマウスで回転させるまでが目的であったが、段々やってみたいことが増えてきた。
- なんでもいいので3次元の図形を描画 (practice1.py)
- 描いた図形をマウスで回転できるようにする (practice2mod.py)
- 表面が連続した四角形からなる物体を描画
- 描いた物体をマウスで回転できるようにする (practice3.py) <--今、ここ。
- 描いた物体をマウスで平行移動したり、拡大縮小したりする
- その他
今回は六面体よりも、頂点数が多い図形を描いてみた(practice3.py)。コードの中で法線ベクトルの計算をしている。
# practice3.py # from OpenGL.GL import * from OpenGL.GLUT import * from OpenGL.GLU import * import sys import math ESCAPE = '\033' class QuadsPicture: def __init__(self): self.lastx = self.x = 30 self.lasty = self.y = 30 glClearDepth(1.0) glEnable(GL_DEPTH_TEST) glClearColor(0.0, 0.5, 0.0, 0.0) glShadeModel(GL_SMOOTH) glMatrixMode(GL_PROJECTION) glFrustum(-0.5, 0.5, -0.5, 0.5, 1.0, 3.0) glMatrixMode(GL_MODELVIEW) glTranslatef(0.0, 0.0, -2.0) glRotatef(self.y, 1.0, 0.0, 0.0) glRotatef(self.x, 0.0, 1.0, 0.0) glEnable(GL_LIGHTING) glEnable(GL_LIGHT0) glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE) glEnable(GL_COLOR_MATERIAL) self.vpos = list() self.readpos() self.displaylist() def readpos(self): #ファイルから頂点座標を読み込む fp = open('coordpos.txt', 'r') num = int(fp.readline()) poss = fp.read().splitlines() for i in xrange(num): self.vpos.append([float(x) for x in poss[i].split(',')]) fp.close() def crossproduct(self, a, b, c): #面の法線ベクトルを計算 cross = [0.0, 0.0, 0.0] cross[0] = (a[1]-b[1])*(c[2]-b[2]) - (a[2]-b[2])*(c[1]-b[1]) cross[1] = (a[2]-b[2])*(c[0]-b[0]) - (a[0]-b[0])*(c[2]-b[2]) cross[2] = (a[0]-b[0])*(c[1]-b[1]) - (a[1]-b[1])*(c[0]-b[0]) cabs = math.sqrt(cross[0]**2+cross[1]**2+cross[2]**2) cc = [x/cabs for x in cross] return cc def mouseMotion(self, x, y): self.lastx = x self.lasty = y glutPostRedisplay() def displaylist(self): ps = self.vpos self.index = glGenLists(1) glNewList(self.index, GL_COMPILE_AND_EXECUTE) glBegin(GL_QUADS) # 四角形の面1 glNormal3fv(self.crossproduct(ps[4],ps[1],ps[0])) glVertex3fv(ps[0]) glVertex3fv(ps[1]) glVertex3fv(ps[4]) glVertex3fv(ps[3]) # 四角形の面2 glNormal3fv(self.crossproduct(ps[5],ps[2],ps[1])) glVertex3fv(ps[1]) glVertex3fv(ps[2]) glVertex3fv(ps[5]) glVertex3fv(ps[4]) # 四角形の面3 ......(続けて頂点の指定。中略)...... glEnd() glEndList() def display(self): glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) glPushMatrix() glRotatef(self.lastx, 0.0, 1.0, 0.0) glRotatef(self.lasty, 1.0, 0.0, 0.0) glCallList(self.index) glPopMatrix() glutSwapBuffers() def keyboard(self, *args): if args[0] == ESCAPE: sys.exit() def reshape(self, w, h): glViewport(0, 0, w, h) def main(): glutInit(sys.argv) glutInitDisplayMode( GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH ) glutInitWindowPosition( 100, 100 ) glutInitWindowSize( 500, 400 ) glutCreateWindow( sys.argv[0] ) qp = QuadsPicture() glutDisplayFunc( qp.display ) glutKeyboardFunc( qp.keyboard ) glutReshapeFunc( qp.reshape ) glutMotionFunc( qp.mouseMotion ) glutMainLoop() print "Hit ESC key to quit." main()