[Edu-sig] And now for something completely different...
Kirby Urner
pdx4d@teleport.com
Thu, 19 Apr 2001 09:28:06 -0700
At 03:31 PM 4/18/2001 -0400, you wrote:
>From: "Kirby Urner" <pdx4d@teleport.com>
>> I've taught my polyhedra to display themselves in .m format, via
>> a lg3d.py module, so now I can provide browsers with interactive
>> views such as found at:
>>
>> http://www.inetarena.com/~pdx4d/ocn/lvmviews.html
>
>Kirby
>
>This is great news!
>
>I would love to see and try your lg3d.py module. Is it posted anywhere?
>
Jason -- I've bundled lg3d.py inside of python101.zip, which is linked
from each of my 'Numeracy + Computer Literacy' pages e.g.
http://www.inetarena.com/~pdx4d/ocn/numeracy0.html -- this zip also
contains vrml.py.
Both lg3d.py and vrml.py are designed to mimic the interface exported
by povray.py, and that's pretty well documented in numeracy1.html --
except that I'm in the process of upgrading povray.py slightly to
make it easier to use textures.
All of these modules work in complement with coords.py, which contains
my general vector classes, e.g. they all give you shaft(v), edge(v1,v2),
point(v), and face(vlist), where v,v1,v2 are vectors and vlist is a
list of vectors.
* shaft(v) draws from the origin to vector tip v,
* edge(v1,v2) draws an edge between the tips of v1 and v2,
* point(v) draws a sphere at the tip of v, and
* face(vlist) makes a polygon going around the points defined
by the vectors in vlist (which should all be coplanar).
The above methods all belong to whatever output object you've chosen,
i.e. some povray or LiveGraphics3D object.
So, for example, you could do something like this:
>>> import povray, coords, lg3d
>>> myfile = povray.Povray("coolgraphic.pov") # instantiate povray object
>>> v1 = coords.Vector((1,0,0)) # define a vector
>>> v2 = coords.Vector((-3,3,0)) # ...and another
>>> myfile.edge(v1,v2) # use vectors to make an edge
>>> myfile.close() # close the povray file
You would now have a file called "coolgraphic.pov" on your disk
ready for rendering in povray, and containing the information
for displaying an edge running from (1,0,0) to (-3,3,0). You could
have instantiated the Povray object with more parameters (e.g.
background color), but just a filename is sufficient.
Or, you might have gone:
>>> myfile = lg3d.Lg3d("coolgraphic.m")
>>> v1 = coords.Vector((1,0,0))
>>> v2 = coords.Vector((-3,3,0))
>>> myfile.edge(v1,v2)
>>> myfile.close()
...which is essentially the same thing, except you've made myfile an
Lg3d object vs. a Povray object -- same methods, but you're creating
"coolgraphic.m" on your disk, suitable for embedding as the
INPUT_FILE in the applet HTML for LiveGraphics3D.
My process for creating the various polyhedra at my website, in LG3D,
Povray or VRML formats, is to use the above technology under a
Polyhedron or Shape class which pre-assigns all the critical vertex
information to vectors, and lists faces as tuples. For example,
my Cube class looks like this:
class Cube(Shape):
"""
Labels of Numbers of
Shape Volume Vertices Vertices, Edges, Faces
---------------------------------------------------------
Duo-tet Cube 3 A-H 8 12 6
"""
faces = [('A','H','C','F'),('A','H','B','G'),('B','E','C','H'),
('B','E','D','G'),('D','G','A','F'),('C','E','D','F')]
sphcolor = cylcolor = "Green"
def __init__(self):
Shape.__init__(self)
self.volume = 3.0
You can see that 'A' must be the name of some vector, which in
this case is actually stored in the module itself as a global
variable. That's the entire cube class definition, as all the
code for translating, scaling and rotating is in the superclass,
i.e. part of Shape's definition (from which Cube inherits).
Note: I don't explicitly give the edges, as these are implied
in the faces list, i.e. I have code that builds a list of
vertex-pairs (edges) from a face-tuple such that ('A','H','C','F')
nets me ('A','H'),('H','C'),('C','F'),('F','A') -- just traveling
around the perimeter. Of doing all the faces this way nets you
each edge twice, so I need to screen for duplications as I build
my edges list. The method looks like this:
def getedges(self):
"""Extract edges from the faces list.
Face lists contain consecutive vertices, so build and edge
list by taking pairs, with the last vertex connecting back
to the first. Use sort() to assure each edge is specified
uniquely
"""
edges = [] # locally scoped
for face in self.faces: # e.g. ['A','B','C']
for j in range(len(face)):
candidate = [face[j],face[j-1]]
candidate.sort() # assure uniqueness
if not tuple(candidate) in edges:
edges.append(tuple(candidate)) # add if new
self.edges = edges
Anyway, that's the kind of stuff I'm doing on the back end.
Kirby