# Plot a 3D function
from image3d import *
import math
MESH = 0
SOLID = 1
SMOOTH = 2
class PlotFunc3D(Image3D):
def __init__(self,func,xmin,ymin,zmin,xmax,ymax,zmax,nx=40,ny=40):
Image3D.__init__(self,xmin,ymin,zmin,xmax,ymax,zmax)
self.lookat(2*max([xmax-xmin,ymax-ymin,zmax-zmin]))
self.autoperspective(40)
self.func = func
self.nxpoints = nx
self.nypoints = ny
self.mode = MESH
# Draw a few primitives
def drawmesh(self):
self.min = self.zmin
self.max = self.zmax
self.newplot()
dx = 1.0*(self.xmax-self.xmin)/self.nxpoints
dy = 1.0*(self.ymax-self.ymin)/self.nypoints
cscale = 240.0/(self.zmax-self.zmin)
zmin = self.zmin
x = self.xmin
for i in xrange(0,self.nxpoints):
y = self.ymin
for j in xrange(0,self.nypoints):
z1 = self.func(x,y)
z2 = self.func(x+dx,y)
z3 = self.func(x+dx,y+dy)
z4 = self.func(x,y+dy)
c1 = cscale*(z1-zmin)
c2 = cscale*(z2-zmin)
c3 = cscale*(z3-zmin)
c4 = cscale*(z4-zmin)
c = (c1+c2+c3+c4)/4
if (c < 0) : c = 0
if c > 239 : c = 239
self.quad(x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,c+16)
y = y + dy
x = x + dx
def drawsolid(self):
self.min = self.zmin
self.max = self.zmax
self.newplot()
dx = 1.0*(self.xmax-self.xmin)/self.nxpoints
dy = 1.0*(self.ymax-self.ymin)/self.nypoints
cscale = 240.0/(self.zmax-self.zmin)
zmin = self.zmin
x = self.xmin
for i in xrange(0,self.nxpoints):
y = self.ymin
for j in xrange(0,self.nypoints):
z1 = self.func(x,y)
z2 = self.func(x+dx,y)
z3 = self.func(x+dx,y+dy)
z4 = self.func(x,y+dy)
c1 = cscale*(z1-zmin)
c2 = cscale*(z2-zmin)
c3 = cscale*(z3-zmin)
c4 = cscale*(z4-zmin)
c = (c1+c2+c3+c4)/4
if (c < 0) : c = 0
if c > 239 : c = 239
self.solidquad(x,y,z1,x+dx,y,z2,x+dx,y+dy,z3,x,y+dy,z4,c+16)
y = y + dy
x = x + dx
def drawsmooth(self):
self.min = self.zmin
self.max = self.zmax
self.newplot()
dx = 1.0*(self.xmax-self.xmin)/self.nxpoints
dy = 1.0*(self.ymax-self.ymin)/self.nypoints
cscale = 240.0/(self.zmax-self.zmin)
zmin = self.zmin
x = self.xmin
for i in xrange(0,self.nxpoints):
y = self.ymin
for j in xrange(0,self.nypoints):
z1 = self.func(x,y)
z2 = self.func(x+dx,y)
z3 = self.func(x+dx,y+dy)
z4 = self.func(x,y+dy)
c1 = cscale*(z1-zmin)
c2 = cscale*(z2-zmin)
c3 = cscale*(z3-zmin)
c4 = cscale*(z4-zmin)
if c1 < 0 : c1 = 0
if c1 > 239 : c1 = 239
if c2 < 0 : c2 = 0
if c2 > 239 : c2 = 239
if c3 < 0 : c3 = 0
if c3 > 239 : c3 = 239
if c4 < 0 : c4 = 0
if c4 > 239 : c4 = 239
self.interpquad(x,y,z1,c1+16,x+dx,y,z2,c2+16,
x+dx,y+dy,z3,c3+16,x,y+dy,z4,c4+16)
y = y + dy
x = x + dx
def draw(self):
self.newplot()
if self.mode == MESH:
self.drawmesh()
elif self.mode == SOLID:
self.drawsolid()
elif self.mode == SMOOTH:
self.drawsmooth()
p = PlotFunc3D(lambda x,y: math.sin(x)*math.cos(y),-5,-5,-2,5,5,2)
p.filename = "plot3d.gif"
p.rotu(60)
p.rotr(30)
p.rotd(10)
p.show()
p.filename = "plot3d_solid.gif"
p.mode = SOLID
p.show()
p.filename = "plot3d_smooth.gif"
p.mode = SMOOTH
p.show()
syntax highlighted by Code2HTML, v. 0.9.1