I recently moving on to the Python.
The first reason is that I wanted to use TensorFlow for future machine learning programming.
The second is the coding style in Python.
It is very intuitive and code readability was quite impressive for me.
Since I was a MATLAB user, however, I was quite disappointed about the interface of
It does not behave as I expected and it is quite hard to draw figures as I expected.
I'm in the field of numerical analysis especially in the finite element method (FEM).
Since I use high order affine element, it is very important that I have full control on the surface patch.
In MATLAB, I usually use
patch to draw figures.
However, I could not find any good reference manipulating patch element on
Since I planning to build my own graphic tools to visualize my data set, I decided to learn GUI programming.
My first choice is
PyOpenGL (if it turns out to be not good for my purpose, I will learn other module).
Since I do not have any experience in GUI programming, it was quite difficult to understand.
How did I learn OpenGL?
I found a good tutorial on from the Youtuber sentdex.
He explains about the PyOpenGL very easily and show very simple examples to help understanding.
What I have learned now is how to draw polygons in 3D.
I used 2 modules,
OpenGL, for the job done.
OpenGL is for the use of
pygame for the interaction with keyboard and mouse.
pygame can be deleted, but it is quite easy to make user interactive interface with this module.
How to draw?
To draw some polygons, I have to do like
import pygame # user interactive from pygame.locals import * # to avoid namespace flooding from OpenGL.GL import * # for basic OpenGL functions from OpenGL.GLU import * # for advanced OpenGL functions import numpy as np # for numpy array and pi def main(): # generate data to draw x, y, n4e = gen_tri_mesh_on_rect(30, 30, 0, 1, 0, 1) # returns x, y, and triangle index z = np.sin(x*np.pi) * np.sin(y*np.pi) pygame.init() display = (800, 600) # canvas size pygame.display.set_mode(display, DOUBLEBUF | OPENGL) # canvas size, double buffur, using OpenGL gluPerspective(45.0, display/display, 0.1, 100.0) # viewing angle, aspect ratio, depth min, depth max glTranslatef(0.0, 0.0, -5) # move camera away from origin by 5 draw_triangles(n4e, x, y, z)
The drawing function for triangle is looks like this.
def draw_triangles(n4e, x, y, z): # n4e : triangle index, x, y, z : coordinate array glBegin(GL_TRIANGLES) # Let OpenGL know that I'm drawing triangles xmid = (min(x)+max(x))/2 # Get mid point ymid = (min(y)+max(y))/2 for tri in n4e: # for every triangle for idx in tri: # for every vertex in each triangle glVertex3fv((x[idx] - xmid, z[idx], y[idx] - ymid)) # feed in triangle vertex glEnd() # end of drawing
nE x 3 integer type array and
x,y,z are 1D array.
Note that I put 3d coordinate for
glVertex3fv in the order of
This is because
PyOpenGL's coordinate system is not the same as in the mathematical plotting.
The consider horizontal direction as
x and vertical direction as
y, and depth as
Therefore, I have to translate
(x,z,y) to get the right position.
Now, I know how to draw triangles.
I also make a loop that takes user input to interact with perspective of resulting plot.
In next post, I will explain how to take input from keyboard and mouse.
Also, it turns out that the code I posted is quite slow even for the small number of triangles.
This is quite unreasonable if we consider 3d game.
They draw easily 10M of polygons per frame.
I think the main reason for the horrible frame rate is because I did not optimize anything.
However, since I'm on the beginning stage, I will stick on this algorithm.
(If you have any idea to optimize this code, please comment below)
One possible way to gain performance is to utilize graphic cards.
There are so called
OpenGL which represents
This stays on the graphic card memory so that I can draw polygons much faster.