[Edu-sig] recent wheel spinning... (spatial geom)

kirby urner kirby.urner at gmail.com
Fri May 11 22:47:55 EDT 2018

Apologies in advance for my ramblings.  Something here might be of interest
to anonymous readers...

Last night and today were all about dusting off old skills and using Python
in a Jupyter Notebook to showcase renderings by the free raytracer POV-Ray (
povray.org).  The topic is pure geometry, no fancy textures required.

In the meantime I'm looking at both Rhino (proprietary) and Blender (open
source), partly because C6XTY / Flextegrity wants to get itself into the
hands of more software engineers and partly because Coding with Kids is
looking at teaching more 2D / 3D graphics (partially covered in the current
suite of tools, but room for growth).

These are both CAD programs for doing 3D animations and renderings, both
with Python APIs.

I learned from my teaching job with kids that even Chromebooks have access
to some kind of Blender in the cloud.  Didn't know that until last week.
This kid sounds like one of our students:  https://youtu.be/JlydssSG5Iw

Here's the Jupyter Notebook in question.  The only dependency is qrays.py
in the same Github repo [and of course povray if the goal is to do


Zooming out:  what I think might interest high schoolers, just learning
about XYZ, spherical coordinates and so on, is some exposure to these
arcane alien esoteric "quadray coordinates" that use 4-tuples instead of
3-tuples to map points in space (no negative numbers required).  I've got
lots of material on 'em but don't claim credit for inventing them (more a
popularizer, implemented 'em in Python and Clojure, Tom Ace in C++).


What's appealing is they're conceptually accessible, not hard to grok, yet
there's so much room for original research.  Clearly four spokes divide
space into four quadrants and any point is reachable by adding up to three
(stretched or shrunk -- but not reversed) per the usual vector scaling and
addition operations.

The centers of all balls in what we call the FCC or CCP packing (core in
crystallography), starting with a nuclear sphere then 1, 12, 42, 92...
balls packing outward in shells (see OEIS [1]) may be given all-integer
4-tuple coordinates using qrays.

Example (these are the 12 ball centers around a nuclear center, at the
corners of a cuboctahedron with origin at (0,0,0,0) (note: ivm_vector is
same thing as qray, of namedtuple type in collections library).

{ivm_vector(a=0, b=1, c=1, d=2),
 ivm_vector(a=1, b=2, c=0, d=1),
 ivm_vector(a=0, b=1, c=2, d=1),
 ivm_vector(a=0, b=2, c=1, d=1),
 ivm_vector(a=2, b=1, c=0, d=1),
 ivm_vector(a=1, b=2, c=1, d=0),
 ivm_vector(a=1, b=1, c=2, d=0),
 ivm_vector(a=2, b=1, c=1, d=0),
 ivm_vector(a=1, b=0, c=2, d=1),
 ivm_vector(a=2, b=0, c=1, d=1),
 ivm_vector(a=1, b=0, c=1, d=2),
 ivm_vector(a=1, b=1, c=0, d=2)}

Today I realized that to add Qrays to a set, they'd need to be (a) hashable
and (b) usable with == i.e. __eq__ would need to have meaning. Without
__eq__, every instance was being seen as unique.  That add to the set OK,
but dupes were not thrown out. They'd hash, but not on the 4-tuple content,
what __eq__ now provides.  Here's that code fragment:

    def __eq__(self, other):
        return self.coords == other.coords

    def __hash__(self):
        return hash(self.coords)

Most recent qrays (there's an ordinary XYZ vector type too -- and the means
to go back and forth):

(I keep updating this, like I notice I need to update the comments to say I
updated the file just today)

The algorithm for getting successive layers of balls (1, 12, 42, 92...) is
to add all 12 balls around every ball in shell N, but then discard (simply
by using the set object for storage) all those balls already in shell N or
shell N-1, generating only balls in shell N+1.

nucleus = {qrays.Qvector((0,0,0,0))}

layer1 = tuple(map(qrays.Qvector,
         ((0, 1, 1, 2), (1, 0, 1, 2),
          (2, 0, 1, 1), (0, 2, 1, 1),
          (0, 1, 2, 1), (1, 2, 1, 0),
          (1, 1, 2, 0), (2, 1, 1, 0),
          (1, 0, 2, 1), (1, 2, 0, 1),
          (2, 1, 0, 1), (1, 1, 0, 2))))

def next_layer(curr_layer, prev_layer):
    next_layer = set()
    for qv in curr_layer:
        for bv in layer1:
            v_sum = qv + bv
            if (not v_sum in curr_layer
                and not v_sum in prev_layer):
    return next_layer

nl   = next_layer(nucleus, nucleus) # 1-freq
nnl  = next_layer(nl, nucleus)      # 2-freq
nnnl = next_layer(nnl, nl)          # 3-freq
print("Number of balls in successive layers:")

If you click on the Notebook you'll see what I mean by "shells".  More here:


Anyway, quadrays or "caltrop coordinates" are pretty freaky and I think
help XYZers better appreciate what the orthodoxy is.  When you've seen
something alien, you better appreciate the status quo.

I took C6XTY out to Saturday Academy on the campus of University of
Portland [2], to see Rhino and Jupyter Notebooks running on Windows7.
Jupyter Notebooks at least is something to have on your resume if thinking
about college.  It's about working with way more than just Python.  I think
I posted those recent articles already.


[1]   http://oeis.org/A005901
(my name under links, still trying to make it viral)

[2]   C6XTY @ sa: this Thursday:

(sa: is where I've taught Martian Math before)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20180511/3fb2ec44/attachment-0001.html>

More information about the Edu-sig mailing list