Python 用PyOpenGL生成三维图形
我正在使用PyOpenGL根据“二维波动方程”生成三维海面。主要目的是显示“二维波动方程”的动态图形。但它不断告诉我这个错误:Python 用PyOpenGL生成三维图形,python,opengl,3d,pyopengl,Python,Opengl,3d,Pyopengl,我正在使用PyOpenGL根据“二维波动方程”生成三维海面。主要目的是显示“二维波动方程”的动态图形。但它不断告诉我这个错误: E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\mytest>python seawave_2d_opengl.py Traceback (most recent call last): File "E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-pack
E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\mytest>python seawave_2d_opengl.py
Traceback (most recent call last):
File "E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\OpenGL\GLUT\
special.py", line 130, in safeCall
return function( *args, **named )
File "seawave_2d_opengl.py", line 106, in Draw
glVertex3f(x,y,z)
File "E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site-packages\OpenGL\p
latform\baseplatform.py", line 402, in __call__
return self( *args, **named )
ctypes.ArgumentError: argument 3: <class 'TypeError'>: wrong type
GLUT Display callback <function Draw at 0x0000000004086950> with (),{} failed: r
eturning None argument 3: <class 'TypeError'>: wrong type
E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\mytest>
E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\mytest>python-seave\u 2d\u opengl.py
回溯(最近一次呼叫最后一次):
文件“E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site packages\OpenGL\GLUT\
safeCall中的special.py“第130行
返回函数(*args,**已命名)
文件“seawave_2d_opengl.py”,第106行,在绘图中
glVertex3f(x,y,z)
文件“E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\lib\site packages\OpenGL\p
latform\baseplatform.py”,第402行,在调用中__
返回self(*args,**已命名)
ctypes.ArgumentError:参数3::错误类型
带(),{}的GLUT显示回调失败:r
eturning None参数3::类型错误
E:\WinPython-64bit-3.4.3.5\python-3.4.3.amd64\mytest>
代码如下:
from numpy import linspace,zeros,sin,pi,exp,sqrt
from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
import sys
def solver0(I, f, c, bc, Lx, Ly, nx, ny, dt, tstop, user_action=None):
dx = Lx/float(nx)
dy = Ly/float(ny)
x = linspace(0, Lx, nx+1) #grid points in x dir
y = linspace(0, Ly, ny+1) #grid points in y dir
if dt <= 0: #max time step?
dt = (1/float(c))*(1/sqrt(1/dx**2 + 1/dy**2))
Cx2 = (c*dt/dx)**2
Cy2 = (c*dt/dy)**2 #help variables
dt2 = dt**2
up = zeros((nx+1,ny+1)) #solution array
u = up.copy() #solution at t-dt
um = up.copy() #solution at t-2*dt
#set initial condition:
t =0.0
for i in range(0,nx):
for j in range(0,ny):
u[i,j] = I(x[i], y[j])
for i in range(1,nx-1):
for j in range(1,ny-1):
um[i,j] = u[i,j] + \
0.5*Cx2*(u[i-1,j] - 2*u[i,j] + u[i+1,j]) + \
0.5*Cy2*(u[i,j-1] - 2*u[i,j] + u[i,j+1]) + \
dt2*f(x[i], y[j], t)
#boundary values of um (equals t=dt when du/dt=0)
i = 0
for j in range(0,ny): um[i,j] = bc(x[i], y[j], t+dt)
j = 0
for i in range(0,nx): um[i,j] = bc(x[i], y[j], t+dt)
i = nx
for j in range(0,ny): um[i,j] = bc(x[i], y[j], t+dt)
j = ny
for i in range(0,nx): um[i,j] = bc(x[i], y[j], t+dt)
if user_action is not None:
user_action(u, x, y, t) #allow user to plot etc.
while t <= tstop:
t_old = t
t += dt
#update all inner points:
for i in range(1,nx-1):
for j in range(1,ny-1):
up[i,j] = -um[i,j] + 2*u[i,j] + \
Cx2*(u[i-1,j] - 2*u[i,j] + u[i+1,j]) + \
Cy2*(u[i,j-1] - 2*u[i,j] + u[i,j+1]) + \
dt2*f(x[i], y[j], t_old)
#insert boundary conditions:
i = 0
for j in range(0,ny): up[i,j] = bc(x[i], y[j], t)
j = 0
for i in range(0,nx): up[i,j] = bc(x[i], y[j], t)
i = nx
for j in range(0,ny): up[i,j] = bc(x[i], y[j], t)
j = ny
for i in range(0,nx): up[i,j] = bc(x[i], y[j], t)
if user_action is not None:
user_action(up, x, y, t)
um, u, up = u, up, um #update data structures
return u #dt might be computed in this function
#Actually,the book wrote `return dt`,but I changed `dt` to `u`
def I(x, y):
return exp(-(x-Lx/2.0)**2/2.0 -(y-Ly/2.0)**2/2.0)
def f(x, y, t):
return sin(2*x*y*pi*t/Lx) #defined by myself
def bc(x, y, t):
return 0.0
#These three functions are some basic functions related to the first function "solver0"
Lx = 10
Ly = 10
c = 1.0
dt = 0
nx = 40
ny = 40
tstop = 20
#The following part is to generate 3D graphics,where I must make mistakes:
def init():
glClearColor(1.0,1.0,1.0,0.0)
def Draw():
glClear(GL_COLOR_BUFFER_BIT)
glColor3f(0,0,1.0)
glBegin(GL_LINES)
for t in range(0,20,1):
z = solver0(I, f, c, bc, Lx, Ly, nx, ny, dt, t, user_action=None)
glVertex3f(x,y,z)
#x and y cannot be used here because they are not defined as global variables.
glEnd()
glFlush
def Update():
global t
t += 0.1
glutPostRedisplay()
def main():
glutInit(sys.argv)
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA)
glutInitWindowSize(800,600)
glutInitWindowPosition(100,50)
glutCreateWindow("2D Wave Equations".encode("cp932"))
init()
glutDisplayFunc(Draw)
glutIdleFunc(Update)
glutMainLoop()
main()
从numpy导入linspace、零、sin、pi、exp、sqrt
从OpenGL.GL导入*
从OpenGL.GLU导入*
从OpenGL.GLUT导入*
导入系统
def解算器0(I、f、c、bc、Lx、Ly、nx、ny、dt、tstop、user_action=None):
dx=Lx/浮点数(nx)
dy=Ly/float(纽约)
x=linspace(0,Lx,nx+1)#x方向上的栅格点
y=linspace(0,Ly,ny+1)#y方向上的栅格点
如果从stacktrace中可以猜到dt,glVertex3f(x,y,z)
中的一个参数(第三个?!?)的类型错误。评论中的讨论清楚地表明,z
是一个二维ndarray
,而glVertex3f()
需要标量。它看起来像是solver0()
计算一个z
值数组,而不是每次调用一个z值
编辑
我现在大致了解了solver0()
的功能。该功能应记录在其印刷所在的书中。虽然Stackoverflow并不是要解释复制和粘贴代码,但我将简要介绍一下我认为该函数的功能:
Lx和Ly给出所有x和y的范围
nx和ny给出了在0和Lx之间使用的x和y值的数量
该函数在计算z值(up
)的位置计算x和y值数组
它以步长dt
计算从0到tstop
的多个时间值的up
如果给定了用户函数user\u action
,则在计算up
后调用该函数。调用userfunction时使用up,x,y,t
作为参数
总而言之:一次调用solver0
计算给定x和y值范围内的所有x、y和z值,以及具有给定分辨率的给定时间跨度。听起来变量z
的类型不正确。检查解算器0(…)
的输出。也许你没有返回结果。@jochen我确实返回了结果。所以z
不能这样定义?我认为z
是一种类型array
…stacktrace指向glVertex3f(x,y,z)
,并告诉您其中一个参数的类型是错误的。只需再次检查所有三个参数的类型(例如,使用打印类型(x)、类型(y)、类型(z)
)。@jochen你是对的。z
的类型是错误的。它显示x和y的类型为numpy.float64
,z的类型为numpy.ndarry
。我怎样才能解决这个问题?我试图通过float(z)
转换z的类型,但没有成功,并且说只有length-1数组可以转换为Python标量
您应该打印z的形状print z.shape
。它将显示z
有多个元素。问题可能是solver0
计算的是z
数组,而不是要绘制的特定x
和y
的z
。我的猜测是基于这样一个事实,x
和y
没有出现在对solver0()
的调用中。对不起,我不太明白你的意思。正如您所知,z
是一个二维的ndarry
,如何使用PyOpenGL解决这个问题?我只想使用glvertex
绘制每个x
y
和z
以生成一个三维曲线图形。请原谅我对这方面知之甚少……不要担心问问题。我不知道solver0()
是如何工作的。你必须先解决这个问题。应该有一些文档,或者你应该联系开发人员。仅仅因为x和y是全局的,并不意味着它们是I
和f
的参数。在I(4,5)
行中,I
的参数将是(4,5)
,而不是全局(x,y)
。不管怎么说,与全球人合作通常不是个好主意。另外,对x中的x使用:是个坏主意,因为这样你就用它的一个元素覆盖了全局x
。哦,我明白了x
和y
未传递到I
和f
…我已将代码粘贴到solver0
。它来自一本书,我做了一些修改。实际上,x
和y
已经在solver0
中定义,但是我不能在这个函数之外使用它,所以我自己在主体中定义了x
和y
,显然我做了一件错误的事情。所以我现在应该做的是找出如何绘制曲线…我又困惑了…我绘制曲线的方法是否错误?以前我用这种方法画了一条二维曲线。所以我自然也用这种方法来绘制3D曲线。但似乎有很多问题。实际上,我希望曲线随着t
移动,以便显示动画。我想我必须修改Draw
函数,但我不知道如何修改…非常感谢您向我解释这些。那么我是否可以将solver0
与OpenGL
结合起来。看来