Earthians (Earthlings) start with a square, subdivided into a grid, and show multiplication as a matter of slicing out rectangles, n x m. Martians, in contrast, start with an equilateral triangle, subdivided into a grid, and show multiplication as a matter of slicing out triangles, also n x m.
The above triangle, in two shades of green, represents 2 x 6 = 12 i.e. the area of the triangle under the red line is equal to that of 12 grid triangles, shown in tan with green borders. If you mentally swivel the lighter green obtuse triangle about a vertex shared in common with a second such area, you may see how the result fills exactly 4 unit triangles. Light green (4) + dark green (8) = 12.
No lets add another edge from the common origin and multiply three numbers instead of two. Below we see what a volume of 2 x 2 x 5 = 20 might look like. Of course any number of tetrahedrons may have the same volume.
This strange way of multiplying is consistent with the Earthling way. The Pythagorean Theorem is still true.
Multiplying inside the IVM, the way Martians do it, provides a canonical OABC for any OA x OB x OC. ABC is "the lid" and simply "closing the lid" is all it takes to define the corresponding volume.
The reason we see these matrix edges as length 2 sometimes is they connect adjacent CCP sphere centers, thinking of spheres as unit radius (R = 1, D = 2). Other times we say D = 1, R = 1/2.
Without the Martian model of multipliction, it makes no sense to see a cube of face diagonals 2, having a volume of 3. Only if the inscribed tetrahedron were unit volume would that make sense, but that's the Martian construct. "Only on Mars does Synergetics ring true" might be some song in the hymnal.
A cube of edges R has S3 times the volume of a tetrahedron of edges D (D = 2R). Each shape (cube and tetrahedron) counts as a unit of volume in its respective systems (XYZ versus IVM). S3 is sometimes called the Synergetics Constant, although more technically it's the Synergetics Constant to the 3rd power.
In :from tetravolume import S3, Tetrahedron from qrays import Qvector print("S3:", S3)
Tetravolumes times 1/S3 gives the corresponding volume in terms of XYZ cubes. The XYZ cube volume times S3 gives the corresponding value in tetravolumes, presuming the calibration defined above. We test that in the code cells below.
The Qvector type, imported above and used below, implements the "Quadray coordinate system" i.e. vectors built from linear combinations of four basis rays from the center of a regular tetrahedron to its four corners.
Think of the methane molecule (carbon in the middle, a hydrogen at each vertex).
p, q, r defined below, represent three vectors from a common origin
(0,0,0,0) that happen to define three corners of the cuboctahedron defining the same regular tetrahedron, of which there are eight all told.
The cuboctahedron consists of 8 regular tetrahedrons and four half-octahedrons, in terms of volume (and shape). Since our canonical octahedron (same length edges as tetrahedron) has volume 4, the cuboctahedron has a volume of 8 + 6 * 2 or 8 + 12 = 20.
Here's the cuboctahedron. The Qvectors
p, q, r point to inter-adjacent balls in the same triangle, from the common origin at the very center of this packing (from the center of the ball at the origin).
In :p = Qvector((2,1,0,1)) q = Qvector((2,1,1,0)) r = Qvector((2,0,1,1)) print(q.angle(p), p.angle(r), r.angle(q))
60.0 60.0 60.0
In :def make_tet(v0,v1,v2): """ three edges from any corner, remaining three edges computed """ tet = Tetrahedron(v0.length(), v1.length(), v2.length(), (v0-v1).length(), (v1-v2).length(), (v2-v0).length()) return tet.ivm_volume(), tet.xyz_volume() def ivm(a,b,c): """ Return the IVM volume of a given tetrahedron. Edges all start from same corner of a regular tet. """ # vectors all mutually 60 degrees e.g. at reg tet corner p = Qvector((2,1,0,1)) q = Qvector((2,1,1,0)) r = Qvector((2,0,1,1)) result = make_tet(a*q, b*p, c*r) # scale as required return result # make_tet returns (ivm_volume, xyz_volume) def xyz(a,b,c): """ Return the XYZ volume of a given tetrahedron. Edges all start from same corner of a regular tet. """ # vectors all mutually 60 degrees e.g. at reg tet corner p = Qvector((2,1,0,1)) q = Qvector((2,1,1,0)) r = Qvector((2,0,1,1)) result = make_tet(a*q, b*p, c*r) # scale as required return result # make_tet returns (ivm_volume, xyz_volume) ivmvol = ivm(2,2,5) xyzvol = xyz(2,2,5) print("IVM volume: ", round(ivmvol, 5)) print("XYZ volume: ", round(xyzvol, 5))
IVM volume: 20.0 XYZ volume: 18.85618
In :xyzvol * S3 == ivmvol
One reason we want to multiply this way is to establish a unit volume tetrahedron. The edges interconnect adjacent unit radius spheres, and so are 2R. The volume is 1.
Sometimes we picture a "tetrahedral book" with two triangular covers lying flat, and a single page turning back and forth, hinged at the spine (like in any book). When the page is straight up vertical, that right tetrahedron of edges D (except for the page tip to cover tip) has a volume equivalent to that of a cube with edges R. So this is another way to show the relationship between two units of volume. The right tetrahedron is bigger than the regular tetrahedron by a scale factor of S3.
In :ivmvol = ivm(1,1,1) print(ivmvol)
Double the length of the edges, and volume increases 8-fold, like in ordinary multiplication.
In :ivmvol = ivm(2,2,2) print(ivmvol)
Lets take a gander at the volume formula we're using behind the scenes:
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 (tetrahedral) and xyz (cubic) units """ def __init__(self, a, b, c, d, e, f): # a,b,c,d,e,f = [Decimal(i) for i in (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 = 1/S3 * 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
Yes, that looks pretty complicated. The algorithm requires only the six edge lengths, three from a point, then three around the lid or opposite face. Thanks to Gerald de Jong for deriving this while using one of Euler's as his model. Notice the IVM volume falls out natively with no constant multiplier. The multiplier comes in, as 1/S3, only when we need the corresponding XYZ volume.