[Edu-sig] PyGeo

Kirby Urner pdx4d@teleport.com
Thu, 02 Mar 2000 10:53:29 -0800

>As to particular design decisions I made with PyGeo, I am certainly 
>open to ideas, suggestions, criticisms.  To the extent you may 
>conclude that I may have gone off-track in designing PyGeo (as 
>relevant to the goals of EDU-SIG), please jump in. I would ideally 
>like to see PyGeo as raw material to play with for those interested
>in the goals of EDU-SIG.

Art, as you say, there's much that's similar between our
respective approaches.  You back end into OpenGL, which
gives students direct and immediate feedback on the 
screen, whereas I back end into Povray.  

You can keep Povray open at the same time as Python, a 
re-render immediately upon re-running a script (even 
outputting to the very same .pov file -- Povray notifies 
you the underlying text file has been changed) but 
your method is still more immediate (as is the method
of drawing diretly to Tk's (flat) canvas, as demoed 
by Python's native /Lib/turtle.py module).

I don't think it has to be either/or.  There are 
advantages and disadvantages to either approach.  For
example, Povray is a free-standing application with
a whole lot of features worth exploring independently
of Python.  OpenGL is likewise a vast topic area unto
itself (more as an API, not as a specific application).  

Some students are heading into the world of ray-tracing, 
and Povray will be a good experience for them, others 
may be heading into a career that requires familiarity 
with OpenGL or other such standard.  Others will benefit
from exposure to both, while some will have occasion 
to use neither. Different walks for different talks.

Although I talked about:

  tri = Triange(p1,p2)

as syntax I'm comfortable with, really my approach has 
been to pass geometric objects to file writer objects.  
That means my vector or shapes classes (which pack in
all the geometry) remain innocent of Povray (and all
the special case syntax that goes with it) -- a good 

So in practice I'm more likely to write something like:

tri = Triangle(p1,p2)        # create triangle object
outfile = Povray("test.pov") # open file writer w/ filename
outfile(tri)                 # feed tri to the file writer               
outfile.close()              # close the file

[then render test.pov in Povray, to see the triangle]

Using this same framework, I'd probably define an OpenGL 
class along similar lines, and just go:

tri = Triangle(p1,p2)        # create triangle object
outwindow = OpenGL(params)   # open draw window
outwindow(tri)               # draw triangle to window
outwindow.close()            # close the window

... something like that anyway.

In the 'Numeracy + Computer Literacy' series, my Povray 
object (defined in povray.py) contains point(v1), shaft(v1), 
edge(v1,v2) and face([v1,v2,...vn]) methods, all of which 
expect one or more vectors as input.  The vector class is
defined in coords.py and, as I've mentioned, is wholly 
ignorant of Povray.

In my Chapter 7 of "Using Polyhedra to Teach OOP and Coordinate 
Geometry Concepts", I have methods to write out entire 
polyhedra: vertices, edges and faces (all of which have 
their own parameters, including simply "on" and "off").  

Again, the polyhedra, all subclasses of the Poly class, 
are ignorant of Povray (or VRML), although they do have 
color attributes (but physical shapes have color 
independently of their applications -- even if math/philo 
texts regard these as strictly "secondary characteristics").

In this latter approach (passing whole polys as objects), 
the POVwriter class is a subclass of a more generic 
Datawriter class, of which VRMLwriter is another, parallel 
subclass (I never finished RWXwriter, which was supposed 
to output in ActiveWorlds format).  I've implemented this 
same design in Java and, to a lesser extent, in Xbase.

When whole shapes get passed to POVwriter (which accepts
any Poly, i.e. Tetrahedron or Octahedron objects get
upcast to their baseclass Poly for passing) you get 
interactive Python sessions that look more like this:

>>> oTet    = polys.Tetra()     # 'o' in oTet means 'object'
>>> oTet2   = polys.Invtetra()  # oTet2 is inverted tetrahedron
>>> oCube   = polys.Cube()      # other polys follow
>>> oOcta   = polys.Octa()
>>> oDodeca = polys.Rhdodeca()
>>> oCubocta= polys.Cubocta()
>>> oFile   = writers.VRMLwriter('cosmic.wrl') # open VRML file
>>> oFile.writeshape(oTet)      # write all these shapes
>>> oFile.writeshape(oTet2)
>>> oFile.writeshape(oCube)
>>> oFile.writeshape(oOcta)
>>> oFile.writeshape(oDodeca)
>>> oFile.writeshape(oCubocta)
>>> oFile.closefile()           # close file

[ view cosmic.wrl in VRML viewer -- so far I've only 
implemented in VRML 1.0, not VRML 2.0 ]