"""
coupler.py
by K. Urner, (gpl) 2007 4dsolutions.net

Documentation for Coupler:

The Coupler is a space-filling irregular octahedron defined
by three mutually orthogonal quadrilaterals:  one square and
two congruent rhombi.  This module constructs these quadri-
laterals and displays them in VPython.

In the concentric hierarchy, the Coupler's volume = 1 (i.e.
is same as tetrahedron's defined by 4 unit-radius CCP balls).

http://www.rwgrayprojects.com/synergetics/s09/figs/f86431.html

URL for stickworks.py:
http://www.4dsolutions.net/ocn/python/stickworks.py

Documentation for stickworks.py:
http://www.4dsolutions.net/ocn/stickworks.html

Relevant VRML worlds by sw dharmraj (see Synergeo on Yahoo!):
http://members.westnet.com.au/dharmraj/vrml/coupler.wrl
http://members.westnet.com.au/dharmraj/vrml/KmiteCube.wrl

See also:  Richard Hawkins Digital Archive:
http://www.newciv.org/Synergetic_Geometry/

"""

from stickworks import Vector, Edge, axes
from math import sqrt

sqrt2 = sqrt(2)
apexd = sqrt2/2.0

# convention nx for -x (negative x)

x = Vector((1,0,0))
y = Vector((0,1,0))
nx = Vector((-1,0,0))
ny = Vector((0, -1, 0))

apex = Vector((0, 0, apexd))
napex = Vector((0, 0, -apexd))


class Square (object) :
    """
    Coupler Square Equator in XY plane
    """

    def __init__(self):
        Edge.color = (1,0,0)
        self.edges = [Edge(x,y), Edge(y,nx),
                      Edge(nx,ny), Edge(ny,x)]

    def draw(self):
        for e in self.edges:
            e.draw()
    
class Fx (object) :
    """
    Coupler Equator in XZ plane
    """

    def __init__(self):
        Edge.color = (0,1,0)        
        self.edges = [ Edge(x, apex), Edge(apex, nx),
                       Edge(nx, napex), Edge(napex, x)]

    def draw(self):
        for e in self.edges:
            e.draw()
    
class Fy (object) :
    """
    Coupler Equator in YZ plane
    """

    def __init__(self):                
        self.edges = [ Edge(y, apex), Edge(apex, ny),
                       Edge(ny, napex), Edge(napex, y)]

    def draw(self):
        for e in self.edges:
            e.draw()
    
def test():
    """
    Draw a Coupler centered at (0,0,0) with XYZ Axes
    """

    # blue axes, please

    Edge.color = (0,0,1)
    axes(2,2,2)

    # create equator objects

    ofy = Fy()
    ofx = Fx()
    osq = Square()

    # draw the rhombi

    Edge.color = (0,1,0)
    ofy.draw()
    ofx.draw()

    # draw the square    

    Edge.color = (1,0,0)    
    osq.draw()

if __name__ == '__main__':
    test()
    
# code highlighted using py2html.py version 0.8