Oregon Curriculum Network
A cube is composed of 24 identical not-regular tetrahedrons, each with a corner at the cube's center, an edge from cube's center to a face center, and two more to adjacent cube corners on that face, defining six edges in all (Fig. 1).
If we define the cube's edges to be √2 then the whole cube would have volume √2 √2 √2 in XYZ units.
However, in IVM units, the very same cube has a volume of 3, owing to the differently-shaped volume unit, a tetrahedron of edges 2, inscribed in this same cube. Fig. 986.210 from Synergetics:
Those lengths would be in R-units, where R is the radius of a unit sphere. In D-units, twice as long (D = 2R), the tetrahedron has edges 1 and the cube has edges √2/2.
By XYZ we mean the XYZ coordinate system of René Descartes (1596 – 1650).
By IVM we mean the "octet-truss", a space-frame consisting of tetrahedrons and octahedrons in a space-filling matrix, with twice as many tetrahedrons as octahedrons.
The tetrahedron and octahedron have relative volumes of 1:4. The question then becomes, how to superimpose the two.
The canonical solution is to start with unit-radius balls (spheres) of radius R. R = 1 in other words, whereas D, the diameter, is 2. Alternatively, we may set D = 1 and R = 0.5, keeping the same 2:1 ratio for D:R.
The XYZ cube has edges R, whereas the IVM tetrahedron has edges D. That relative sizing convention brings their respective volumes fairly close together, with the cube's volume exceeding the tetrahedron's by about six percent.
import math xyz_volume = math.sqrt(2)**3 ivm_volume = 3 print("XYZ units:", xyz_volume) print("IVM units:", ivm_volume) print("Conversion constant:", ivm_volume/xyz_volume)
XYZ units: 2.8284271247461907 IVM units: 3 Conversion constant: 1.060660171779821
The Python code below encodes a Tetrahedron type based solely on its six edge lengths. The code makes no attempt to determine the consequent angles.
A complicated volume formula, mined from the history books and streamlined by mathematician Gerald de Jong, outputs the volume of said tetrahedron in both IVM and XYZ units.
The unittests that follow assure it's producing the expected results.
from math import sqrt, hypot class Tetrahedron: """ Takes six edges of tetrahedron with faces (a,b,d)(b,c,e)(c,a,f)(d,e,f) -- returns volume in ivm and xyz units """ def __init__(self, a,b,c,d,e,f): self.a, self.a2 = a, a**2 self.b, self.b2 = b, b**2 self.c, self.c2 = c, c**2 self.d, self.d2 = d, d**2 self.e, self.e2 = e, e**2 self.f, self.f2 = f, f**2 def ivm_volume(self): ivmvol = ((self._addopen() - self._addclosed() - self._addopposite())/2) ** 0.5 return ivmvol def xyz_volume(self): xyzvol = sqrt(8/9) * self.ivm_volume() return xyzvol def _addopen(self): a2,b2,c2,d2,e2,f2 = self.a2, self.b2, self.c2, self.d2, self.e2, self.f2 sumval = f2*a2*b2 sumval += d2 * a2 * c2 sumval += a2 * b2 * e2 sumval += c2 * b2 * d2 sumval += e2 * c2 * a2 sumval += f2 * c2 * b2 sumval += e2 * d2 * a2 sumval += b2 * d2 * f2 sumval += b2 * e2 * f2 sumval += d2 * e2 * c2 sumval += a2 * f2 * e2 sumval += d2 * f2 * c2 return sumval def _addclosed(self): a2,b2,c2,d2,e2,f2 = self.a2, self.b2, self.c2, self.d2, self.e2, self.f2 sumval = a2 * b2 * d2 sumval += d2 * e2 * f2 sumval += b2 * c2 * e2 sumval += a2 * c2 * f2 return sumval def _addopposite(self): a2,b2,c2,d2,e2,f2 = self.a2, self.b2, self.c2, self.d2, self.e2, self.f2 sumval = a2 * e2 * (a2 + e2) sumval += b2 * f2 * (b2 + f2) sumval += c2 * d2 * (c2 + d2) return sumval PHI = sqrt(5)/2 + 0.5 R =0.5 D =1.0 tet = Tetrahedron(D, D, D, D, D, D) print(tet.ivm_volume())
import unittest class Test_Tetrahedron(unittest.TestCase): def test_unit_volume(self): tet = Tetrahedron(D, D, D, D, D, D) print(tet.ivm_volume()) self.assertAlmostEqual(tet.ivm_volume(), 1.0, places=5) def test_unit_volume(self): tet = Tetrahedron(R, R, R, R, R, R) self.assertAlmostEqual(tet.xyz_volume(), 0.11785, places=5) def test_phi_edge_tetra(self): tet = Tetrahedron(D, D, D, D, D, PHI) self.assertAlmostEqual(tet.ivm_volume(), 0.70711, places=5) def test_right_tetra(self): e = hypot(sqrt(3)/2, sqrt(3)/2) # right tetrahedron tet = Tetrahedron(D, D, D, D, D, e) self.assertAlmostEqual(tet.xyz_volume(), 1.0, places=5) a = Test_Tetrahedron() R =0.5 D =1.0 suite = unittest.TestLoader().loadTestsFromModule(a) unittest.TextTestRunner().run(suite)
... ---------------------------------------------------------------------- Ran 3 tests in 0.005s OK
<unittest.runner.TextTestResult run=3 errors=0 failures=0>
a = 2 b = 4 c = 5 d = 3.4641016151377544 e = 4.58257569495584 f = 4.358898943540673 tetra = Tetrahedron(a,b,c,d,e,f) print("IVM volume of tetra:", tetra.ivm_volume())
IVM volume of tetra: 39.99999999999998
Lets define a MITE, one of these 24 identical space-filling tetrahedrons, with reference to D=1, R=0.5, as this is how our Tetrahedron class is calibrated. The cubes 12 edges will all be √2/2.
Edges 'a' 'b' 'c' fan out from the cube center, with 'b' going up to a face center, with 'a' and 'c' to adjacent ends of the face's edge.
From the cube's center to mid-face is √2/4 (half an edge), our 'b'. 'a' and 'c' are both half the cube's body diagonal of √(3/2)/2 or √(3/8).
Edges 'd', 'e' and 'f' define the facet opposite the cube's center.
'd' and 'e' are both half face diagonals or 0.5, whereas 'f' is a cube edge, √2/2. This gives us our tetrahedron:
b = sqrt(2)/4 a = c = sqrt(3/8) d = e = 0.5 f = sqrt(2)/2 mite = Tetrahedron(a, b, c, d, e, f) print("IVM volume of Mite:", mite.ivm_volume()) print("XYZ volume of Mite:", mite.xyz_volume())
IVM volume of Mite: 0.12499999999999994 XYZ volume of Mite: 0.11785113019775786
Allowing for floating point error, this space-filling right tetrahedron has a volume of 0.125 or 1/8. Since 24 of them form a cube, said cube has a volume of 3. The XYZ volume, on the other hand, is what we'd expect from a regular tetrahedron of edges 0.5 in the current calibration system.
regular = Tetrahedron(0.5, 0.5, 0.5, 0.5, 0.5, 0.5) print("MITE volume in XYZ units:", regular.xyz_volume()) print("XYZ volume of 24-Mite Cube:", 24 * regular.xyz_volume())
MITE volume in XYZ units: 0.11785113019775792 XYZ volume of 24-Mite Cube: 2.82842712474619
The MITE (minimum tetrahedron) further dissects into component modules, a left and right A module, then either a left or right B module. Outwardly, the positive and negative MITEs look the same. Here are some drawings from R. Buckminster Fuller's research, the chief popularizer of the A and B modules.
In a different Jupyter Notebook, we could run these tetrahedra through our volume computer to discover both As and Bs have a volume of 1/24 in IVM units.
Instead, lets take a look at the E-module and compute its volume.
The black hub is at the center of the RT, as shown here...
from math import sqrt as rt2 from tetravolume import make_tet, Vector ø = (rt2(5)+1)/2 e0 = Black_Yellow = rt2(3)*ø**-1 e1 = Black_Blue = 1 e3 = Yellow_Blue = (3 - rt2(5))/2 e6 = Black_Red = rt2((5 - rt2(5))/2) e7 = Blue_Red = 1/ø # E-mod is a right tetrahedron, so xyz is easy v0 = Vector((Black_Blue, 0, 0)) v1 = Vector((Black_Blue, Yellow_Blue, 0)) v2 = Vector((Black_Blue, 0, Blue_Red)) # assumes R=0.5 so computed result is 8x needed # volume, ergo divide by 8. ivm, xyz = make_tet(v0,v1,v2) print("IVM volume:", ivm/8) print("XYZ volume:", xyz/8)
IVM volume: 0.04173131692777364453602187865 XYZ volume: 0.03934466291663160686315718999
This information is being shared around Portland in various contexts. Below, an image from a hands-on workshop in 2010 organized by the Portland Free School.