[Edu-sig] Those polyhedra again (ch.py)

kirby urner kirby.urner at gmail.com
Thu Apr 15 01:58:32 CEST 2010


"""
This version adds an instance variable self.keep
that propagates though the scaling method to
the next of kin.  For example:

>>> import ch
>>> c = ch.Cube()
>>> c.volume
3
>>> c.keep
[]
>>> bigc = c * 2
>>> bigc.volume
24
>>> c.keep.append("gem")
>>> c.keep
['gem']
>>> bigc.keep
['gem']
>>>


"""

from math import sqrt as radical

phi = (1 + radical(5))/2

class Poly( object):

    def __init__(self,  edge = 1, edge_name = "edge",
                 volume = 1, greekname = "Tetrahedron",
                 platonic = True, dual = "Tetrahedron", keep=[]):
        self.edge = edge
        self.edge_name = edge_name
        self.volume = volume
        self.greekname = greekname
        self.platonic = platonic
        self.dual = dual
        self.keep = keep

    def scale(self, scalefactor):
        edge = self.edge * scalefactor  # edge unbound to self
        volume = self.volume * pow(scalefactor, 3)  # likewise volume
        # print("DEBUG:  a star is born: a new %s" % self.__class__.__name__)
        return self.__class__(*(edge, self.edge_name, volume, self.greekname,
                              self.platonic, self.dual, self.keep))

    __mul__ = __rmul__ = scale # e.g. tetra = tetra * 3

    def __repr__(self):
        return "Polyhedron of type %s (vol: %s)" % (self.greekname, self.volume)

class Tetra( Poly ):
    pass

class Cube( Poly ):
    def __init__(self, edge = 1, edge_name = "any face diagonal",
                 volume = 3, greekname = "Cube",
                 platonic=True, dual="Octahedron", keep=[]):
        super(Cube, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual, keep))

class Octa( Poly ):
    def __init__(self, edge = 1, edge_name = "any edge",
                 volume = 4, greekname = "Octahedron",
                 platonic=True, dual="Cube", keep=[]):
        super(Octa, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual, keep))

class R_Dodeca( Poly ):
    def __init__(self, edge = 1, edge_name = "any long face diagonal",
                 volume = 6, greekname = "Rhombic Dodecahedron",
                 platonic=False, dual="Cuboctahedron",keep=[]):
        super(R_Dodeca, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual, keep))

class R_Triac( Poly ):
    def __init__(self, edge = radical(2)/2, edge_name = "any long face
diagonal",
                 volume = 7.5, greekname = "Rhombic Triacontahedron",
                 platonic=False, dual="Icosidodecahedron", keep=[]):
        super(R_Triac, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual, keep))

class Icosa ( Poly ):
    def __init__(self, edge = 1.0, edge_name = "any edge",
                 volume = 5 * phi**2 * radical(2), greekname = "Icosahedron",
                 platonic=True, dual="Pentagonal Dodecahedron", keep=[]):
        super(Icosa, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual, keep))

class P_Dodeca ( Poly ):
    def __init__(self, edge = 1/phi, edge_name = "any edge",
                 volume = (phi**2 + 1) * 3 * radical(2), greekname =
"Pentagonal Dodecahedron",
                 platonic=True, dual="Icosahedron", keep=[]):
        super(P_Dodeca, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual))

class Cubocta ( Poly ):
    def __init__(self, edge = 1, edge_name = "any edge",
                 volume = 20, greekname = "Cuboctahedron",
                 platonic=False, dual = "Rhombic Dodecahedron", keep=[]):
        super(Cubocta, self).__init__(*(edge, edge_name, volume,
greekname, platonic, dual))

def test1():
    c = Cube()
    print "First shape: %s" % c
    print "Dual: %s  Platonic: %s" % (c.dual, c.platonic)

    d = P_Dodeca()
    print "Second shape: %s" % d
    print "Dual: %s  Platonic: %s" % (d.dual, d.platonic)

def test2():
    print "\n\nVolumes Table\n============="
    for shape in (Tetra(), Cube(), Octa(), R_Triac()*pow(2./3,1./3),
                  R_Dodeca(), R_Triac(), P_Dodeca(), Icosa(), Cubocta()):
        poly = "{0} ({1} = {2:.4g})".format(shape.greekname,
shape.edge_name, shape.edge)
        print "{0:<60}{1:>8.4g}".format(poly, shape.volume)

def test3():
    print "\n\nDuals Table\n=========="
    for shape in (Tetra(), Cube(), Octa(), R_Dodeca(), R_Triac(),
P_Dodeca(), Icosa(), Cubocta()):
        print "{0:<30}{1}".format(shape.greekname+"
*"[int(shape.platonic)], shape.dual)
    print "\n * = Platonic"

if __name__ == "__main__":

    # test1()
    test2()
    test3()


More information about the Edu-sig mailing list