1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
# 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()
|