glDrawPixels and numpy problems - python

I'm trying to visualize mandelbrot set using numpy and OpenGL. However I have problems in drawing code, that is glDrawPixels.
When I draw using glDrawPixels I get something black and all messed up, but when using slower method of glBegin & glEnd I get the correct result. Code:
#!/usr/bin/env python3
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from pylab import *
from numpy import *
from time import clock
w,h = 80,60
eps = 2
max_iter = 30
def draw():
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
t = clock()
print("Being calculation")
x = linspace(-1.5, 0.5, w)
y = linspace(-1,1,h)
a, b = meshgrid(x,y)
M = (a + 1j*b).T
Alive = ones((w,h), dtype=bool)
C = M.copy()
esc = max_iter * ones((w,h), dtype=int32)
for k in range(max_iter):
M[Alive] = square(M[Alive]) + C[Alive]
esc[logical_and(Alive, abs(M) > eps)] = k
Alive = abs(M) < eps
colorsMap = array([0x8B0000FF, 0xA52A2AFF, 0xB22222FF, 0xDC143CFF, 0xFF0000FF, 0xFF6347FF, 0xFF7F50FF, 0xCD5C5CFF, 0xF08080FF, 0xE9967AFF, 0xFA8072FF, 0xFFA07AFF, 0xFF4500FF, 0xFF8C00FF, 0xFFA500FF, 0xFFD700FF, 0xB8860BFF, 0xDAA520FF, 0xEEE8AAFF, 0xBDB76BFF, 0xF0E68CFF, 0x808000FF, 0xFFFF00FF, 0x9ACD32FF, 0x556B2FFF, 0x6B8E23FF, 0x7CFC00FF, 0x7FFF00FF, 0xADFF2FFF, 0x006400FF, 0x008000FF, 0x228B22FF, 0x00FF00FF, 0x32CD32FF, 0x90EE90FF, 0x98FB98FF, 0x8FBC8FFF, 0x00FA9AFF, 0x00FF7FFF, 0x2E8B57FF, 0x66CDAAFF, 0x3CB371FF, 0x20B2AAFF, 0x2F4F4FFF, 0x008080FF, 0x008B8BFF, 0x00FFFFFF, 0x00FFFFFF, 0xE0FFFFFF, 0x00CED1FF, 0x40E0D0FF, 0x48D1CCFF, 0xAFEEEEFF, 0x7FFFD4FF, 0xB0E0E6FF, 0x5F9EA0FF, 0x4682B4FF, 0x6495EDFF, 0x00BFFFFF, 0x1E90FFFF, 0xADD8E6FF, 0x87CEEBFF, 0x87CEFAFF, 0x191970FF, 0x000080FF, 0x00008BFF, 0x0000CDFF, 0x0000FFFF, 0x4169E1FF, 0x8A2BE2FF, 0x4B0082FF, 0x483D8BFF, 0x6A5ACDFF, 0x7B68EEFF, 0x9370DBFF, 0x8B008BFF, 0x9400D3FF, 0x9932CCFF, 0xBA55D3FF, 0x800080FF, 0xD8BFD8FF, 0xDDA0DDFF, 0xEE82EEFF, 0xFF00FFFF, 0xDA70D6FF, 0xC71585FF, 0xDB7093FF, 0xFF1493FF, 0xFF69B4FF, 0xFFB6C1FF, 0xFFC0CBFF, 0xFAEBD7FF, 0xF5F5DCFF, 0xFFE4C4FF, 0xFFEBCDFF, 0xF5DEB3FF, 0xFFF8DCFF, 0xFFFACDFF, 0xFAFAD2FF, 0xFFFFE0FF, 0x8B4513FF, 0xA0522DFF, 0xD2691EFF, 0xCD853FFF, 0xF4A460FF, 0xDEB887FF, 0xD2B48CFF, 0xBC8F8FFF, 0xFFE4B5FF, 0xFFDEADFF, 0xFFDAB9FF, 0xFFE4E1FF, 0xFFF0F5FF, 0xFAF0E6FF, 0xFDF5E6FF, 0xFFEFD5FF, 0xFFF5EEFF, 0xF5FFFAFF, 0x708090FF, 0x778899FF, 0xB0C4DEFF, 0xE6E6FAFF, 0xFFFAF0FF, 0xF0F8FFFF, 0xF8F8FFFF, 0xF0FFF0FF, 0xFFFFF0FF, 0xF0FFFFFF, 0xFFFAFAFF], dtype=uint32)
cmap = zeros((w,h), dtype=uint32)
for k in range(max_iter):
cmap[esc == k] = colorsMap[k]
print("Finish Calculation: {:.2f}".format(clock() - t))
t = clock()
print("Begin Drawing")
if True: #Change for effect
glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, cmap.data)
else:
#Primite drawing numpy array
def transform(cl):
r = ((cl >> 24) & 0xFF) / 256.0
b = ((cl >> 16) & 0xFF) / 256.0
g = ((cl >> 8) & 0xFF) / 256.0
return (r,b,g)
glBegin(GL_POINTS)
for y in range(0,h):
for x in range(0,w):
glColor3f(*transform(cmap[x,y]))
glVertex2i(x,y)
glEnd()
glFlush()
print("Finish drawing: {:.2f}".format(clock() - t))
def idle():
glutPostRedisplay()
def reshape(width, height):
global w,h
w,h =width, height
glViewport(0, 0, width, height)
glMatrixMode(GL_PROJECTION)
glLoadIdentity()
gluOrtho2D(0, width, height, 0)
glClearColor( 1., 1., 1., 0.)
glClear( GL_COLOR_BUFFER_BIT )
glPointSize(1.0)
glColor3f(0., 0., 0.)
glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB)
glutInitWindowSize(w,h)
glutInitWindowPosition(100,100)
glutCreateWindow("Fraktali")
glutReshapeFunc(reshape)
glutDisplayFunc(draw)
glutMainLoop()

glDrawPixels() expects the data in row-major ("raster scan") order, whereas mine array was in column-major order. Didn't know that was how numpy saved data in memory. This solved the problem:
glDrawPixels(w, h, GL_RGBA, GL_UNSIGNED_INT_8_8_8_8, ascontiguousarray(cmap.transpose()).data)
Thanks to user GClements on openGL forum.

Related

Graph optimization functions with manim

I need help to make an optimization graph in 3 dimensions with manim. I am having difficulty understanding how to use the projection methods and to represent the axes and data in three-dimensional space. If anyone has experience with manim and can help me understand how to do it, I would greatly appreciate it. Thank you
Note: I am trying to graph the schewefel function below I attach part of the code that I have been working on
%%manim -qm -v WARNING AckleyAnimation
class Schewefel(ThreeDScene):
def func(self,u,v):
return x * np.sin(np.sqrt(np.abs(x))) + y * np.sin(np.sqrt(np.abs(y)))
def construct(self):
cielo = '#C4DDFF'
azul = '#001D6E'
rojo = "#B20600"
axes = ThreeDAxes()
self.set_camera_orientation(phi=65*DEGREES,theta=60*DEGREES)
# self.add(axes,x,y)
name_function = Tex(r"Schwefel function." ,font_size=38).to_corner(UL)
self.add_fixed_in_frame_mobjects(name_function)
funcion = MathTex(r"f(x) = 418.9829d - \sum_{i=1}^{d} x_i \sin \sqrt{|x_i|}", font_size=30).to_corner(UL)
self.play(Write(name_function))
self.play(FadeOut(name_function))
self.add_fixed_in_frame_mobjects(funcion)
self.play(Write(funcion))
surface_plane = Surface(
lambda u, v: np.array([u, v, self.func(u, v)]),
u_range=[-100,100],
v_range=[-100,100],
resolution=(50, 50))
self.play(Write(surface_plane))
Graphics
function Schewefel
Correction:
So far I modified the script and I have the following
%%manim -qm -v WARNING PlotSurfaceExample
class PlotSurfaceExample(ThreeDScene):
def construct(self):
resolution_fa = 16
self.set_camera_orientation(phi=75 * DEGREES, theta=-60 * DEGREES)
axes = ThreeDAxes(x_range=(-500, 500, 1800), y_range=(-500, 500, 1800), z_range=(-500, 500, 1800))
def param_trig(u, v):
x = u
y = v
z = x * np.sin(np.sqrt(np.abs(x))) + y * np.sin(np.sqrt(np.abs(y)))
return z
trig_plane = axes.plot_surface(
param_trig,
resolution=(resolution_fa, resolution_fa),
u_range = (-500, 500),
v_range = (-500, 500),
colorscale = [BLUE, GREEN, YELLOW, ORANGE, RED],
)
self.add(axes)
self.play(Write(trig_plane))
but it gives me this result
but nevertheless I hope this

PyOpenGL code with vbos for rendering tile-based game creating blank screen

I have been, with pygame and pyopengl (oh and obviously Python), been trying to make a little tile-based 2D game, but I'm having trouble with the rendering using VBOs and glMultiDrawArray().
The program runs without errors, but I don't see any geometry drawn, so it's just a blank screen.
I've tried using glTranslate to see if maybe the geometry is being drawn, but I can't see it, as well as changing between using GluPerspective() and glOrthro2D(). No luck. I've pored over the code to see where it isn't working, but I have no clue what could be wrong. I'm still struggling to understand OpenGL and VBOs.
Here are the relevant bits of my code:
The Chunk class. Every chunk has its own VBO for vertices and textures (textures are currently unused)
class Chunk():
def __init__(self, position):
self.Position = position
self.VertexVBOId = _get_chunk_id()
self.VertexVBO = glGenBuffers(self.VertexVBOId)
self.TextureVBOId = _get_chunk_id()
self.TextureVBO = glGenBuffers(self.TextureVBOId)
Chunks[str(position)] = self
self.__updateVertexArray()
# glBindBuffer (GL_ARRAY_BUFFER, self.VertexVBO)
#self.__updateVertexArray()
def __getvertices(self):
vertices = []
for x in range(self.Position.x, self.Position.x + 16):
for y in range(self.Position.y, self.Position.y + 16):
pos = Vector2(x, y)
tile = GetTile(pos)
if tile != "air":
vertices.append(x+1)
vertices.append(y)
vertices.append(x+1)
vertices.append(y+1)
vertices.append(x)
vertices.append(y+1)
vertices.append(x)
vertices.append(y)
return vertices
def __updateVertexArray(self): #This will be called when a change is made the the chunk, as well as once initially
print("UPDATING VERTEX ARRAY")
vertices = self.__getvertices()
glBindBuffer (GL_ARRAY_BUFFER, self.VertexVBOId)
glBufferData (GL_ARRAY_BUFFER, len(vertices)*4, (c_float*len(vertices))(*vertices), GL_DYNAMIC_DRAW)
And here is the rendering loop:
def main():
print("Started")
pygame.init()
global displaySize
global SCREENSIZE
global PIXELS_PER_TILE
pygame.display.set_mode(displaySize, DOUBLEBUF|OPENGL)
#gluOrtho2D(-SCREENSIZE[0]/2, SCREENSIZE[0]/2, -SCREENSIZE[1]/2, SCREENSIZE[1]/2)
gluPerspective(180, 2, 0.1, 100)
... some other stuff ...
while True:
#Drawing
glClearColor(0.7, 0.7, 1, 0)
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
cameraTranslateX = (camera.Position.x % 1) * PIXELS_PER_TILE
cameraTranslateY = (camera.Position.y % 1) * PIXELS_PER_TILE
#Figure out which chunks to render
botLeft = camera.Position - Vector2(SCREENSIZE[0]/2, SCREENSIZE[1]/2) + Vector2(cameraTranslateX, cameraTranslateY)
topRight = camera.Position + Vector2(SCREENSIZE[0]/2, SCREENSIZE[1]/2) + Vector2(cameraTranslateX, cameraTranslateY)
FirstChunkPos = (botLeft/16).floor()
TotalChunksX = (topRight/16).ceil().x - FirstChunkPos.x
TotalChunksY = (topRight/16).ceil().y - FirstChunkPos.y
for x in range(TotalChunksX):
for y in range(TotalChunksY):
pos = Vector2(x + FirstChunkPos.x, y + FirstChunkPos.y)
chunk = Chunks.get(str(pos))
if not chunk:
chunk = Chunk(pos)
VertexVBO = chunk.VertexVBOId
glBindBuffer (GL_ARRAY_BUFFER, VertexVBO)
glVertexPointer (2, GL_FLOAT, 0, None)
TextureVBO = chunk.TextureVBOId
glMultiDrawArrays (GL_POLYGON, vertexArrayThingy1, vertexArrayThingy2, 255)
# glUnmapBuffer(GL_ARRAY_BUFFER,VertexVBO)
pygame.display.flip ()
The 2nd and 3rd arguments of glMultiDrawArrays are of type const GLint* and const GLsizei*. This function cannot draw from different buffers. There is no glDraw* command that can use multiple vertex buffers for drawing. All vertecx attributes must be in one and the same buffer. glMultiDrawArrays should draw different ranges from the buffer. Suppose you want to draw the following 3 attribute ranges [3:6], [18:27], [30:36]:
first = [3, 18, 30]
count = [3, 9, 6]
glMultiDrawArrays(GL_TRIANGLES, first, count, 3)
If you want to draw multiple lists of indices you have to use glMultiDrawElements and you have to create an array of pointers to arrays of indices:
import ctypes
ia1 = (GLuint * 6)(0, 1, 2, 0, 2, 3)
ia2 = (GLuint * 6)(12, 13, 14, 12, 14, 15)
counts = [6, 6]
indexPtr = (GLvoidp * 2)(ctypes.addressof(ia1), ctypes.addressof(ia2))
glMultiDrawElements(GL_TRIANGLES, counts, GL_UNSIGNED_INT, indexPtr, 2)

How to solve Newton's Gravity equations when both bodies are moving

I am struggling to numerically solve Newton's equation for gravity using scipy.integrate.solve_ivp. I can get the coding working when one of the bodies is assumed stationary. However as shown in the picture when I use the code below where I am trying to account for the force of the sun on Jupiter and that of Jupiter on the sun, the suns orbit is not correct. It doesn't seem to wobble but instead just heads off away from the COM.
G = 6.67408e-11
msun = 1988500e24
m_jupiter = 1898.13e24
x_pos_j = 2.939022030646856E+00*au
y_pos_j = -4.169544536356319E+00*au
z_pos_j = -4.843813063988785E-02*au
x_vel_j = 6.083727195546033E-03*v_factor
y_vel_j = 4.708328571996785E-03*v_factor
z_vel_j = -1.556609498459863E-04*v_factor
def f_grav(t, y):
x1, x2, x3, v1, v2, v3 = y
# x1_star, x2_star, x3_star = x_other
dydt = [v1,
v2,
v3,
-(x1-x1_star)*G*m/((x1-x1_star)**2+(x2-x2_star)**2+(x3-x3_star)**2)**(3/2),
-(x2-x2_star)*G*m/((x1-x1_star)**2+(x2-x2_star)**2+(x3-x3_star)**2)**(3/2),
-(x3-x3_star)*G*m/((x1-x1_star)**2+(x2-x2_star)**2+(x3-x3_star)**2)**(3/2)]
return dydt
x_jupiter = np.array([x_pos_j, y_pos_j, z_pos_j])
x_sun = np.array([0, 0, 0])
v_sun = np.array([0, 0, 0])
tStart = 0e0
t_End = 20*year
dt = t_End/3000
# minstep = dt/100
domain = (tStart, dt)
temp_end = dt
x1_star, x2_star, x3_star = [0, 0, 0]
init_j = [x_pos_j, y_pos_j, z_pos_j, x_vel_j, y_vel_j, z_vel_j]
init_sun = [20, -20, 20, 15, -15, 0]
while tStart < t_End:
m=msun
ans_j = solve_ivp(fun=f_grav, t_span=domain, y0=init_j)
x1_star, x2_star, x3_star = ans_j['y'][0:3, -1]
v1_star, v2_star, v3_star = ans_j['y'][3:6, -1]
x_jupiter = np.vstack((x_jupiter, (ans_j['y'][0:3, -1])))
init_j = [x1_star, x2_star, x3_star, v1_star, v2_star, v3_star]
# print(init_j[0:3])
m=m_jupiter
ans_sun = solve_ivp(fun=f_grav, t_span=domain, y0=init_sun)
x1_star, x2_star, x3_star = ans_sun['y'][0:3, -1]
v1_star, v2_star, v3_star = ans_sun['y'][3:6, -1]
v_sun = np.vstack((v_sun, (ans_sun['y'][3:6, -1])))
x_sun = np.vstack((x_sun, (ans_sun['y'][0:3, -1])))
init_sun = [x1_star, x2_star, x3_star, v1_star, v2_star, v3_star]
tStart += dt
temp_end = tStart + dt
domain = (tStart,temp_end)
plt.plot(x_jupiter[:,0], x_jupiter[:,1])
plt.plot(x_sun[:,0], x_sun[:,1])
plt.show()
In the code at any given moment to solve the equation I assume that the other star is stationary but only for dt, which I don't think should effect the results. Is this why my plots are wrong and if so how can I better solve the equation when both bodies are moving. The orbit of Jupiter (blue on right image) looks more less correct but not that of the sun (on both images and is orange).

Linux OpenGL code fails, works on Mac & Windows

I have a fairly complex Python based OpenGL code that runs fine on Windows and Mac, but fails with weird banded-spheres on Linux. Views from two angles:
Here is what the same code plots on a Mac:
The problem is not only with spheres, but this is the easiest thing to show. Does this problem suggest anything to anyone with more experience with OpenGL than I?
Thanks for any hints or suggestions.
Here is some sample code that shows this problem
'''Draws a sphere and axis triplet with openGL; rotates with mouse drag.
This works fine on Windows and Mac, but sphere displays strangely on Linux
'''
import sys
import math
import numpy as np
import numpy.linalg as nl
import wx
import wx.glcanvas
import OpenGL.GL as GL
import OpenGL.GLU as GLU
drawingData = {
'oldxy' : [0, 0],
'Quaternion' : np.array([ 0.11783419, 0.87355958, 0.09141639, 0.4633053 ]),
'linecolors': [(np.array([[0, 0, 0], [1, 0, 0]]), [255, 0, 0]),
(np.array([[0, 0, 0], [0, 1, 0]]), [ 0, 255, 0]),
(np.array([[0, 0, 0], [0, 0, 1]]), [ 0, 0, 255])],
}
def Q2Mat(Q):
''' make rotation matrix from quaternion
'''
QN = Q/np.sqrt(np.sum(np.array(Q)**2))
aa = QN[0]**2
ab = QN[0]*QN[1]
ac = QN[0]*QN[2]
ad = QN[0]*QN[3]
bb = QN[1]**2
bc = QN[1]*QN[2]
bd = QN[1]*QN[3]
cc = QN[2]**2
cd = QN[2]*QN[3]
dd = QN[3]**2
M = [[aa+bb-cc-dd, 2.*(bc-ad), 2.*(ac+bd)],
[2*(ad+bc), aa-bb+cc-dd, 2.*(cd-ab)],
[2*(bd-ac), 2.*(ab+cd), aa-bb-cc+dd]]
return np.array(M)
def prodQVQ(Q,V):
"""compute the quaternion vector rotation qvq-1 = v'
"""
T2 = Q[0]*Q[1]
T3 = Q[0]*Q[2]
T4 = Q[0]*Q[3]
T5 = -Q[1]*Q[1]
T6 = Q[1]*Q[2]
T7 = Q[1]*Q[3]
T8 = -Q[2]*Q[2]
T9 = Q[2]*Q[3]
T10 = -Q[3]*Q[3]
M = np.array([[T8+T10,T6-T4,T3+T7],[T4+T6,T5+T10,T9-T2],[T7-T3,T2+T9,T5+T8]])
VP = 2.*np.inner(V,M)
return VP+V
def invQ(Q):
'''get inverse of quaternion q=r+ai+bj+ck; q* = r-ai-bj-ck
'''
return Q*np.array([1,-1,-1,-1])
def AVdeg2Q(A,V):
''' convert angle (degrees) & vector to quaternion
q=r+ai+bj+ck
'''
sind = lambda x: math.sin(x*math.pi/180.)
cosd = lambda x: math.cos(x*math.pi/180.)
Q = np.zeros(4)
d = nl.norm(np.array(V))
if not A: #== 0.!
A = 360.
if d:
V = V/d
p = A/2.
Q[0] = cosd(p)
Q[1:4] = V*sind(p)
else:
Q[3] = 1.
return Q
def prodQQ(QA,QB):
''' Grassman quaternion product, QA,QB quaternions; q=r+ai+bj+ck
'''
D = np.zeros(4)
D[0] = QA[0]*QB[0]-QA[1]*QB[1]-QA[2]*QB[2]-QA[3]*QB[3]
D[1] = QA[0]*QB[1]+QA[1]*QB[0]+QA[2]*QB[3]-QA[3]*QB[2]
D[2] = QA[0]*QB[2]-QA[1]*QB[3]+QA[2]*QB[0]+QA[3]*QB[1]
D[3] = QA[0]*QB[3]+QA[1]*QB[2]-QA[2]*QB[1]+QA[3]*QB[0]
return D
def RenderUnitVectors(x,y,z):
'Show the axes'
GL.glEnable(GL.GL_COLOR_MATERIAL)
GL.glLineWidth(2)
GL.glEnable(GL.GL_BLEND)
GL.glBlendFunc(GL.GL_SRC_ALPHA,GL.GL_ONE_MINUS_SRC_ALPHA)
GL.glEnable(GL.GL_LINE_SMOOTH)
GL.glPushMatrix()
GL.glTranslate(x,y,z)
GL.glScalef(1,1,1)
GL.glBegin(GL.GL_LINES)
for line,color in drawingData['linecolors']:
GL.glColor3ubv(color)
GL.glVertex3fv(-line[1]/2.)
GL.glVertex3fv(line[1]/2.)
GL.glEnd()
GL.glPopMatrix()
GL.glColor4ubv([0,0,0,0])
GL.glDisable(GL.GL_LINE_SMOOTH)
GL.glDisable(GL.GL_BLEND)
GL.glDisable(GL.GL_COLOR_MATERIAL)
def RenderSphere(x,y,z,radius,color):
'show a sphere'
GL.glMaterialfv(GL.GL_FRONT_AND_BACK,GL.GL_DIFFUSE,color)
GL.glPushMatrix()
GL.glTranslate(x,y,z)
GL.glMultMatrixf(np.eye(4).T)
GLU.gluSphere(GLU.gluNewQuadric(),radius,20,10)
GL.glPopMatrix()
class myGLCanvas(wx.Panel):
def __init__(self, parent, id=-1,dpi=None,**kwargs):
wx.Panel.__init__(self,parent,id=id,**kwargs)
if 'win' in sys.platform: # for Windows (& darwin==Mac) -- already double buffered
attribs = None
else: # Linux
attribs = [wx.glcanvas.WX_GL_DOUBLEBUFFER,]
self.canvas = wx.glcanvas.GLCanvas(self,-1,attribList=attribs,**kwargs)
self.context = wx.glcanvas.GLContext(self.canvas)
self.canvas.SetCurrent(self.context)
sizer=wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.canvas,1,wx.EXPAND)
self.SetSizer(sizer)
self.canvas.Bind(wx.EVT_MOTION, self.OnMouseMove)
self.Draw()
self.Draw()
return
def OnMouseMove(self,event):
if not event.Dragging():
drawingData['oldxy'] = list(event.GetPosition())
return
# Perform a rotation in x-y space
oldxy = drawingData['oldxy']
if not len(oldxy): oldxy = list(event.GetPosition())
dxy = event.GetPosition()-oldxy
drawingData['oldxy'] = list(event.GetPosition())
V = np.array([dxy[1],dxy[0],0.])
A = 0.25*np.sqrt(dxy[0]**2+dxy[1]**2)
if not A: return
# next transform vector back to xtal coordinates via inverse quaternion & make new quaternion
Q = drawingData['Quaternion']
V = prodQVQ(invQ(Q),np.inner(np.eye(3),V))
Q = prodQQ(Q,AVdeg2Q(A,V))
drawingData['Quaternion'] = Q
self.Draw()
def Draw(self):
GL.glClearColor(0.,0.,0.,0.)
GL.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT)
GL.glInitNames()
GL.glPushName(0)
GL.glMatrixMode(GL.GL_PROJECTION)
GL.glLoadIdentity()
GL.glViewport(0,0,*self.canvas.GetSize())
GLU.gluPerspective(20.,self.canvas.GetSize()[0]*1./self.canvas.GetSize()[1],7.5,12.5)
GLU.gluLookAt(0,0,10,0,0,0,0,1,0)
# Set Lighting
GL.glEnable(GL.GL_DEPTH_TEST)
GL.glEnable(GL.GL_LIGHTING)
GL.glEnable(GL.GL_LIGHT0)
GL.glLightModeli(GL.GL_LIGHT_MODEL_TWO_SIDE,0)
GL.glLightfv(GL.GL_LIGHT0,GL.GL_AMBIENT,[1,1,1,1])
GL.glLightfv(GL.GL_LIGHT0,GL.GL_DIFFUSE,[1,1,1,1])
GL.glMatrixMode(GL.GL_MODELVIEW)
GL.glLoadIdentity()
matRot = Q2Mat(drawingData['Quaternion'])
matRot = np.concatenate((np.concatenate((matRot,[[0],[0],[0]]),axis=1),[[0,0,0,1],]),axis=0)
GL.glMultMatrixf(matRot.T)
GL.glMultMatrixf(np.eye(4).T)
Tx,Ty,Tz = (0.20045985394544949, 0.44135342324377724, 0.40844172594191536)
GL.glTranslate(-Tx,-Ty,-Tz)
RenderUnitVectors(Tx,Ty,Tz)
RenderSphere(0, 0, 0, 0.804, [1., 1., 1.])
self.canvas.SetCurrent(self.context)
self.canvas.SwapBuffers()
class GUI(wx.App):
def OnInit(self):
frame = wx.Frame(None,-1,'ball rendering',wx.DefaultPosition,wx.Size(400,400))
frame.Show()
wx.CallAfter(myGLCanvas,frame,size=wx.Size(400,400)) # wait for frame to be displayed
self.MainLoop()
return True
if __name__ == '__main__':
GUI()
You have to specify the number of the bits for the depth buffer, according to the conditions of your hardware, by setting WX_GL_DEPTH_SIZE. The size of the depth buffer should be 16, 24 or 32.
attribs = [
wx.glcanvas.WX_GL_RGBA,
wx.glcanvas.WX_GL_DOUBLEBUFFER,
wx.glcanvas.WX_GL_DEPTH_SIZE, 16]
See also:
How can I determine the max allowable WX_GL_DEPTH_SIZE for a wx GLCanvas?
OpenGL depth buffer deosn't seem to work in wx.glcanvas?
wx.glcanvas.WX_GL_DEPTH_SIZE
wxGLCanvas

Python Pattern Design

I'm trying to achieve the pattern below.
Got as far as doing the first line, then I have no clue how to code the rest of the pattern.
Here's what I've done so far:
#Timothy Shek
from graphics import*
#open Graph Window
def main():
win = GraphWin("Example",100,100)
x = 7
y = 7
radius = 5
while x<=30 :
centre = Point(x,y)
circle1 = Circle(centre,radius)
circle1.setFill("red")
circle1.draw(win)
x = x+10
while x>=35 and x<=65 :
centre = Point(x+5,y)
circle2 = Circle(centre,radius)
circle2.setFill("red")
circle2.draw(win)
x = x+10
print(x)
while x>=67:
centre = Point(x+10,y)
circle1 = Circle(centre,radius)
circle1.setFill("red")
circle1.draw(win)
x = x+10
main()
I got it guys, thanks
Heres the solution
#Timothy Shek
from graphics import*
#open Graph Window
def main():
win = GraphWin("Patch2" ,100,100)
for x in (5, 15, 25, 40,50,60,75,85,95):
for y in (5, 15, 25, 40,50,60,75,85,95):
c = Circle(Point(x+2,y), 5)
d = Circle(Point(x+2,y), 5)
c.draw(win)
d.draw(win)
c.setFill("Red")
d.setFill("Red")
if x==15 or x==50 or x== 85:
if y==15 or y==50 or y== 85:
c2 = Circle(Point(x+2,y),5)
c2.draw(win)
c2.setFill("White")
main()
While there is nothing wrong with your solution, this is a bit more performant
from graphics import *
def main():
win = GraphWin("Patch2" ,100,100)
coords = [5, 15, 25, 40, 50, 60, 75, 85, 95]
centers = set([coords[i] for i in range(1, len(coords), 3)])
for i in xrange(len(coords)):
for j in xrange(i+1):
x, y = (coords[i], coords[j])
c1 = Circle(Point(x+2,y), 5)
c2 = Circle(Point(y+2,x), 5)
c1.draw(win)
c2.draw(win)
if x in centers and y in centers:
c1.setFill("White")
c2.setFill("White")
else:
c1.setFill("Red")
c2.setFill("Red")
main()
Update: "Better" version
And since I got bored and I liked this problem (yes, I program when I'm bored) I made a fully parameter-ized version which you can do some fun stuff with, like.
Probably over your head :) But maybe you learn something from it, so I'm posting it.
from graphics import *
def drawPattern(scale):
# Inner method: Draw a square of circles given the top-left point
def drawSquare(win, xCoord, yCoord, squareSize=30, numCircles=3, scale=1, scaleCircles=False, outer_color="Red", inner_color="White"):
# Overwrite the default scaling
if scale > 1:
squareSize *= scale
if scaleCircles:
numCircles *= scale
radius = squareSize/(numCircles*2) # Divide by 2 since it's the radius
from math import sqrt, floor
centerDiff = (2*radius) * floor(sqrt(numCircles)) # Used for drawing off-color circles
# xrange uses an exclusive stop value, so go one value past to make inclusive
for x in xrange(radius, squareSize+radius, radius*2):
for y in xrange(squareSize-radius, x-radius, -radius*2):
c1 = Circle(Point(x+xCoord+2,y+yCoord), radius)
c2 = Circle(Point(y+yCoord+2,x+xCoord), radius)
c1.draw(win)
c2.draw(win)
if (centerDiff < x < squareSize - centerDiff) and (centerDiff < y < squareSize - centerDiff):
c1.setFill(inner_color)
c2.setFill(inner_color)
else:
c1.setFill(outer_color)
c2.setFill(outer_color)
win = GraphWin("Patch2 (x{})".format(scale), 100*scale,100*scale)
coords = [0, 35, 70]
for x in coords:
for y in coords:
drawSquare(win, x*scale, y*scale, scale=scale) # normal (boring) version
# drawSquare(win, x*scale, y*scale, scale=scale, scaleCircles=True, outer_color="Blue") # Picture version
def main():
drawPattern(3)
main()

Categories

Resources