{ "cells": [ { "cell_type": "raw", "metadata": {}, "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Bean Stalk Series: Dissecting the E & E3\n", "#### by D. Koski & K. Urner, May 2018 (version 1.2), last modified Mar 1, 2025\n", "\n", "
\n", "
\n", "\n", "
\n", "\"E\n", "
\n", "Figure 1: E3 module dissected into Fum, Foe, Fie and Fee\n", "
\n", "
\n", "\n", "What we see here is another vZome construction by David Koski, showing an E3 module dissected into four sub-modules, according to how the great circles of the 120 LCD Triangles cross the RT as chords. Compare with [Figure 986.561](http://www.rwgrayprojects.com/synergetics/s09/figs/f86561.html) in Synergetics.\n", "\n", "
\n", "\"Excerpt\n", "
\n", "\n", "What are their volumes?\n", "\n", "Lets start with E itself." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "sqrt(2)/(8*(1/2 + sqrt(5)/2)**3)\n", "0.041731316927773654299439512001665297072526423571415\n" ] } ], "source": [ "import sympy\n", "from sympy import sqrt as rt2\n", "import pandas as pd\n", "\n", "root2 = rt2(2)\n", "root3 = rt2(3)\n", "root5 = rt2(5)\n", "\n", "ø = (root5 + 1)/2\n", "ø_down = ø ** -1\n", "ø_up = ø\n", "\n", "E_vol = (15 * root2 * ø_down ** 3)/120 # a little more than 1/24, volume of T module\n", "print(E_vol)\n", "print(E_vol.evalf(50))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now lets import the tetravolume.py module, which in turn has dependencies, to get these volumes directly, based on edge lengths. I'll use the edges given in [Fig. 986.411](http://www.rwgrayprojects.com/synergetics/s09/figs/f86411a.html) of Synergetics, spoking out from the point C at the center of any RT diamond, and/or values computed by David Koski.\n", "\n", "First, lets get a color coded version of the E module...\n", "
\n", "
\n", "\n", "
\n", "\"LCD\n", "
\n", "Figure 2: Dissected E-mod with color-coded vertexes (Koski with vZome)\n", "
\n", "
\n", "\n", "
\n", "The black hub is at the center of the RT, as shown here...\n", "\n", "
\n", "\n", "
\n", "\"E\n", "
\n", "Figure 3: RT center is the black hub (Koski with vZome)\n", "
\n", "
\n", "\n", "
\n", "\n", "The edges of the Fum module, tetrahedron Black-Orange-Yellow-Blue will be... (note R=1, D=2):" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Edge e0 = 1.0704662693192697958\n", "Edge e1 = 1.0000000000000000000\n", "Edge e2 = 1.0514622242382672121\n", "Edge e3 = 0.38196601125010515180\n", "Edge e4 = 0.32491969623290632616\n", "Edge e5 = 0.20081141588622727987\n", "Edge e6 = 1.1755705045849462583\n", "Edge e7 = 0.61803398874989484820\n", "Edge e8 = 0.72654252800536088590\n", "Edge e9 = 1.0803630269509058144\n", "Edge e10 = 0.14589803375031545539\n" ] } ], "source": [ "# Edges needed for Fum and Emod\n", "e0 = Black_Yellow = root3 * ø_down\n", "e1 = Black_Blue = sympy.Integer(1) # radius of RT = 1 (same as unit-radius sphere)\n", "e2 = Black_Orange = 1/(rt2(ø**2+1)/2)\n", "e3 = Yellow_Blue = (3 - root5)/2\n", "e4 = Blue_Orange = (ø**-1)*(1/rt2(ø**2+1))\n", "e5 = Orange_Yellow = rt2(Yellow_Blue**2 - Blue_Orange**2)\n", "\n", "e6 = Black_Red = rt2((5 - root5)/2)\n", "e7 = Blue_Red = 1/ø\n", "e8 = Red_Yellow = rt2(5 - 2 * root5)\n", "\n", "#print(e3 ** 2 + e7 ** 2)\n", "#print(e8 ** 2)\n", "#assert e3 ** 2 + e7 ** 2 == e8 ** 2 # check\n", "#assert e4 ** 2 + e5 ** 2 == e3 ** 2 # check\n", "\n", "# not needed for this computation\n", "e9 = Black_Green = 20/(5 * root2 * ø**2) # Sfactor\n", "e10 = Purple_Green = ø ** -4\n", "\n", "for e in range(11):\n", " val = \"e\" + str(e)\n", " length = eval(val).evalf(20)\n", " print(\"Edge {:3} = {:f}\".format(val, length))" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fum volume (in tetravolumes): 0.011534252319777869899586549348544481968647598057779\n", "E volume (in tetravolumes) : 0.041731316927773654299439512001665297072526423571415\n" ] } ], "source": [ "import tetravolume as tv # has to be in your path, stored on Github with this JN\n", "# D = 1 in this module, so final volume need to be divided by 8 to match R=1 (D=2)\n", "# see Fig. 986.411A in Synergetics\n", "\n", "Fum_vol = tv.Tetrahedron(e0,e1,e2,e3,e4,e5).ivm_volume()/8\n", "E_vol = tv.Tetrahedron(e1,e0,e6,e3,e8,e7).ivm_volume()/8\n", "print(\"Fum volume (in tetravolumes): {:f}\".format( Fum_vol.evalf(50) ))\n", "print(\"E volume (in tetravolumes) : {:f}\".format( E_vol.evalf(50) ))" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "ø = sympy.Symbol('ø')\n", "Fee = (ø**-7) * (rt2(2)/8)\n", "Fie = (ø**-6) * (rt2(2)/8)\n", "Foe = ((5-rt2(5))/5) * (ø**-4) * (rt2(2)/8)\n", "Fum = (rt2(5)/5) * (ø**-4)*(rt2(2)/8)\n", "Fee_Fie = (ø**-5) * (rt2(2)/8)\n", "Foe_Fum = (ø**-4) * (rt2(2)/8)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Fee: 0.0060885170855734312960401922215060412396082765810203\n", "Fie: 0.0098514275855422639024530425195510715311032901364582\n", "Foe: 0.014257119936880089201359727912063702333167258796158\n", "Fum: 0.011534252319777869899586549348544481968647598057779\n", "E_vol: 0.041731316927773654299439512001665297072526423571415\n", "E_vol: 0.041731316927773654299439512001665297072526423571415\n" ] } ], "source": [ "print(\"Fee: {:f}\".format(Fee.evalf(50, subs={ø:(root5 + 1)/2})))\n", "print(\"Fie: {:f}\".format(Fie.evalf(50, subs={ø:(root5 + 1)/2})))\n", "print(\"Foe: {:f}\".format(Foe.evalf(50, subs={ø:(root5 + 1)/2})))\n", "print(\"Fum: {:f}\".format(Fum.evalf(50, subs={ø:(root5 + 1)/2})))\n", "print(\"E_vol: {:f}\".format((Fee_Fie + Foe_Fum).evalf(50, subs={ø:(root5 + 1)/2})))\n", "print(\"E_vol: {:f}\".format(((ø**-3)*(rt2(2)/8)).evalf(50, subs={ø:(root5 + 1)/2})))" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
formulaenumerics
Fesqrt(2)/(8*ø**7)0.0060885170855734312960401922215060412396082765810203
Fisqrt(2)/(8*ø**6)0.0098514275855422639024530425195510715311032901364582
Fosqrt(2)*(1 - sqrt(5)/5)/(8*ø**4)0.014257119936880089201359727912063702333167258796158
Fumsqrt(10)/(40*ø**4)0.011534252319777869899586549348544481968647598057779
\n", "
" ], "text/plain": [ " formulae \\\n", "Fe sqrt(2)/(8*ø**7) \n", "Fi sqrt(2)/(8*ø**6) \n", "Fo sqrt(2)*(1 - sqrt(5)/5)/(8*ø**4) \n", "Fum sqrt(10)/(40*ø**4) \n", "\n", " numerics \n", "Fe 0.0060885170855734312960401922215060412396082765810203 \n", "Fi 0.0098514275855422639024530425195510715311032901364582 \n", "Fo 0.014257119936880089201359727912063702333167258796158 \n", "Fum 0.011534252319777869899586549348544481968647598057779 " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df = pd.DataFrame(data = {\"formulae\": [Fee, Fie, Foe, Fum],\n", " \"numerics\": [alg.evalf(50, subs={ø:(root5 + 1)/2}) \n", " for alg in (Fee, Fie, Foe, Fum)]},\n", " index = [\"Fe\", \"Fi\", \"Fo\", \"Fum\"])\n", "pd.set_option(\"display.max_colwidth\", 60)\n", "df" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle 0.041731316927773654299439512001665297072526423571415$" ], "text/plain": [ "0.041731316927773654299439512001665297072526423571415" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df.numerics.sum()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "One may also place an e3 module, E-phi-down, on its side atop an E, thereby capping its Fe, Fi, Fo, Fum with Phe, Phi, Pho, Phum, the way David Koski writes it. I've been using 3-letters for the F4 series, but mainly because I neglected to remember P4.\n", "\n", "\"Phe" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{\\sqrt{2}}{8 ø^{7}}$" ], "text/plain": [ "sqrt(2)/(8*ø**7)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Fee" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{\\sqrt{2}}{8 ø^{6}}$" ], "text/plain": [ "sqrt(2)/(8*ø**6)" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Fie" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{\\sqrt{2} \\cdot \\left(1 - \\frac{\\sqrt{5}}{5}\\right)}{8 ø^{4}}$" ], "text/plain": [ "sqrt(2)*(1 - sqrt(5)/5)/(8*ø**4)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Foe" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{\\sqrt{10}}{40 ø^{4}}$" ], "text/plain": [ "sqrt(10)/(40*ø**4)" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Fum" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "True" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "Fie == Fee * ø" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{1}{ø}$" ], "text/plain": [ "1/ø" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(Fee / Fie).evalf()" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle ø$" ], "text/plain": [ "ø" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(Fie / Fee).evalf()" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle ø$" ], "text/plain": [ "ø" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ø.evalf()" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "text/latex": [ "$\\displaystyle \\frac{0.176776695296637}{ø^{6}}$" ], "text/plain": [ "0.176776695296637/ø**6" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(ø * Fee).simplify().evalf()" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.176776695296636881100211090526212259821208984422118509147085/ø**4 + 0.176776695296636881100211090526212259821208984422118509147085/ø**6 + 0.176776695296636881100211090526212259821208984422118509147085/ø**7\n", "0.0417313169277736542994395120016652970725264235714150850630182\n" ] } ], "source": [ "print((Fee + Fie + Foe + Fum).evalf(60))\n", "print(E_vol.evalf(60))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Lets start with a Pentagonal Dodecahedron and build it from Es + e3s." ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "3*sqrt(2)*(ø**2 + 1)\n", "4.2426406871192851464050661726290942357090156261308*ø**2 + 4.2426406871192851464050661726290942357090156261308\n" ] } ], "source": [ "PD = 3 * root2 * (ø ** 2 + 1)\n", "print(PD)\n", "print(PD.evalf(50))" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "15.350018208050781864011005748221813389851871774315\n" ] } ], "source": [ "E = e = E_vol # shorthand (E3 = E * ø_up ** 3, e3 = E * ø_down ** 3, E = e)\n", "e3 = e * ø_down ** 3\n", "PD = 348 * E + 84 * e3\n", "print(PD.evalf(50))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "RT3, on the other hand, has a volume we may express as:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.041731316927773654299439512001665297072526423571415\n", "21.213203435596425732025330863145471178545078130654\n" ] } ], "source": [ "RT3 = 480 * E + 120 * e3 # e3 is e * ø_down ** 3 (e = E)\n", "print(E.evalf(50))\n", "print(RT3.evalf(50))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Recall RT3 is the Rhombic Triacontahedron we get by intersecting the two Platonic duals: Icosahedron (Icosa) and Pentagonal Dodecahedron (PD), with the former having edges = 2R and volume ~18.51 (5 \\* rt2(2) \\* ø \\*\\* 2).\n", "\n", "It turns out that if we shave a Fum3 off an E3, and multiply by 120, we get the PD's volume.\n", "\n", "Put another way: RT3 - PD leaves a volume of 120 Fum3 volumes. In other words 120 * (E3 - Fum3) = PD." ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "0.17677669529663688110021109052621225982120898442212\n", "0.048859876896213698900119375957697148239110052969494\n", "5.8631852275456438680143251149236577886932063563393\n", "5.8631852275456438680143251149236577886932063563393\n" ] } ], "source": [ "E3 = E_vol * ø_up ** 3\n", "Fum3 = Fum_vol * ø_up ** 3\n", "print(E3.evalf(50))\n", "print(Fum3.evalf(50))\n", "print((RT3 - PD).evalf(50))\n", "print((120 * Fum3).evalf(50))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As you can see, the relationship holds, though floating point numbers add some noise.\n", "\n", "In addition to edge lengths, we have a succinct way to express the angles of this LCD triangle in terms of ø, thanks to David Koski." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "10.452578723944649\n", "13.282525588538993\n", "20.905157447889298\n", "31.717474411461005\n", "37.37736814064969\n", "0.7853981633974483\n", "0.7853981633974483\n", "1.1071487177940904\n", "1.1071487177940906\n", "63.43494882292202\n", "1.2490457723982542\n", "1.2490457723982544\n", "71.56505117707799\n" ] } ], "source": [ "from math import atan, sqrt as rt2, degrees\n", "\n", "Ø = (1 + rt2(5))/2 # back to floating point\n", "\n", "print(degrees(atan(Ø**-2)/2)) # 10.812316º\n", "print(degrees(atan(Ø**-3))) # 13.282525º\n", "print(degrees(atan(Ø**-2))) # 20.905157º\n", "print(degrees(atan(Ø**-1))) # 31.717474º\n", "print(degrees(atan(2*Ø**-2))) # 37.377368º\n", "\n", "print(atan(Ø ** -1) + atan(Ø ** -3))\n", "print(atan(1)) # arctan 1 = 45º\n", "\n", "print(2 * atan(Ø**-1))\n", "print(atan(2)) # 63.434948º\n", "print(degrees(atan(2))) # 63.434948º\n", "\n", "print( atan(Ø**-1) + 3 * atan(Ø**-3) )\n", "print(atan(3)) # 71.565051º\n", "print(degrees(atan(3))) # 71.565051º" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For Further Reading:\n", "* [Cuboidal E3](https://github.com/4dsolutions/Python5/blob/master/CuboidalE3.ipynb)\n", "* [Terminology and Scope](http://worldgame.blogspot.com/2017/10/terminology-and-scope.html)\n", "* [Escaping the Vortex of Standardized Tests](https://medium.com/@kirbyurner/escaping-the-vortex-of-standardized-tests-a-game-plan-84d77d75d100)\n", "* [S&E Modules (Python 3 Repl)](https://repl.it/@kurner/SandE-Modules)\n", "* [Figure 986.411A in Synergetics](http://www.rwgrayprojects.com/synergetics/s09/figs/f86411a.html)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.11.3" } }, "nbformat": 4, "nbformat_minor": 4 }