To start, let's take a step back and look at the definitions for bracketopes and toratopes. The bracketopes are constructed from three products:
- max(|x|,|y|) : creates hypercubes; Cartesian product
- sqrt(x^2+y^2) : creates hyperspheres
- |x|+|y| : creates tegums
- Cartesian product
- sqrt(x^2+y^2) : creates hyperspheres
- sqrt(x^2+y^2)-r : creates tori
You may see some connections between the two groups under this definition. What if we generalize the use of sqrt(x^2+y^2)-r to any of the three bracketopic products? We can simplify this to get 4 different products:
- max(|x|,|y|) : creates hypercubes; Cartesian product
- sqrt(x^2+y^2) : creates hyperspheres
- |x|+|y| : creates tegums
- x - r : creates tori
It turns out that this generalization works pretty well to merge the ideas of toratopes and bracketopes together in a mathematically precise way.
Notation
Extending the notation used for bracketopes is usually more helpful for bracketoratopes than attempting it with toratopes. Like usual, an I represents a free variable in an equation, [] represents the Cartesian product, () represents the circular product, <> represents the tegmal product, and redundant brackets are removed because of associativity (e.g. [[(II)I]I] = [(II)[II]] = [(II)II] ). The additional operator we add is the torus operation, which simply subtracts a constant. I represent it with an asterisk *. Because every shape needs at least 1 value for a radius at its outermost brackets, we remove the asterisk from our representation. For example, the torus is represented as ((II)*I) in our notation, because it has an equation of sqrt( sqrt(x^2+y^2) - r1 + z^2 ) - r2 = 0. Note that because <II> and [II] are both squares, we can always default to [II] in our notation.
Bracketopes look the same in this notation as they did in their original notation, but toratopes look different and can take some time to get used to. I've compiled a short list of some small closed toratopes and their new representations:
(III) : Sphere
((II)*I) : Torus
[((II)*I)I] : Torinder
(IIII) : Glome
((II)*II) : Spheritorus
((III)*I) : Torisphere
((II)*(II)*) : Tiger
(((II)*I)*I) : Ditorus
(((II)*(II)*)*I) : Toratiger
(((II)*I)*(II)*) : Cyltorintigroid
((((II)*I)*I)*I) : Tritorus
Generally, we can add an asterisk to any pair of brackets within brackets and use square brackets for a Cartesian product.
Finding toratope types
Look at this list of bracketoratopes:
[[III]*I] , ((III)*I) , <<[II]I>*I> , <<(II)I>*I> , <[III]*I> , [[(II)I]*I] , (([II]I)*I) , <[(II)I]*I> , [([II]I)*I] , [(III)*I] , [<III>*I] , [<(II)I>*I] , ([III]*I) , ([(II)I]*I) , (<III>*I) , (<(II)I>*I) , <[(II)I]*I> , <([II]I)*I> , <(III)*I>
Although they are all different shapes, they are similar in a way to the torisphere ((III)*I). They have different products applied to them, but the location of the torus operation remains the same and the brackets themselves stay in the same location. Because of this, these bracketoratopes are all part of the same toratope type, that of the torisphere. Toratope types can be helpful to fit bracketoratopes into categories, and every closed toratope has one.
However, it's not just the closed toratopes that have types. Take these two bracketoratopes:
- <[II]*(II)> , (<[II]*I>I)
However, we can distinguish between these two if we allow certain open toratopes. Take the torinder [((II)*I)I]. It has the same structure as our second shape {{{II}*I}I}, but unlike before [((II)*I)I] ≠ [(II)*[II]], and so this toratope does distinguish the two. Because of this, (<[II]*I>I)'s type is the torinder, and <[II]*(II)>'s type is the spheritorus. Toratopes that we use to distinguish different shapes that we otherwise wouldn't also have their own types. If a toratope t has a type, then we call the set of bracketoratopes with type t t-like. We give the convex shapes a single type for simplicity, because these are just the bracketopes.
Naming scheme
We name the bracketoratopes in the following way:
Convex bracketoratopes are already named, they're just the bracketopes.
Non-convex bracketoratopes are either a toratope and already have a name, or are part of a toratope type. If the latter is true, we remove all torus operations from the bracketoratope, and then take the resulting bracketope and combine it with its type.
For example, the previously mentioned (<[II]*I>I)'s name is the octahedral crind torinder, because (<[II]I>I) is the octahedral crind and (<[II]*I>I)'s toratope type is the torinder.
3D bracketoratopes
Here is an enumeration of all 12 3D bracketorapes. These are a lot easier to understand with some images, so here they are:
Convex:
[III] : Cube
<III> : Octahedron
(III) : Sphere
[(II)I] : Cylinder
([II]I) : Crind
<(II)I> : Bicone
Torus-like:
((II)*I) : Torus
[[II]*I] : Cubic torus
<[II]*I> : Octahedral torus
([II]*I): Crindal torus
<(II)*I> : Biconic torus
[(II)*I] : Cylindrical torus
4D bracketoratopes
There are too many 4D bracketoratopes for me to render them all here. However, to showcase the similarities of toratope types and to give an idea of what 4D bracketopes actually look like, I created a video for the tiger-like bracketoratopes here.
Convex:
[IIII] : Tesseract
(IIII) : Glome
<IIII> : Hexadecachoron
[(II)II] : Cubinder
([II]II) : Dicrind
<(II)II> : Dibicone
[(II)(II)] : Duocylinder
([II][II]) : Duocrind
<(II)(II)> : Duocircular tegum
[([II]I)I] : Crindal prism
[(III)I] : Spherinder
[<III>I] : Octahedral prism
[<(II)I>I] : Biconic prism
([III]I) : Cubic crind
([(II)I]I) : Cylindrical crind
(<III>I) : Octahedral crind
(<(II)I>I) : Biconic crind
<[(II)I]I> : Bicylindrone
<([II]I)I> : Crindal bipyramid
<[III]I> : Cubic bipyramid
<(III)I> : Bisphone
Torinder-like:
[((II)*I)I] : Torinder
[([II]*I)I] : Crindal prism torinder
[<[II]*I>I] : Octahedral prism torinder
[<(II)*I>I] : Biconic prism torinder
([[II]*I]I) : Cubic crind torinder
([(II)*I]I) : Cylindrical crind torinder
(<[II]*I>I) : Octahedral crind torinder
(<(II)*I>I) : Biconic crind torinder
<[(II)*I]I> : Bicylindrone torinder
<([II]*I)I> : Crindal bipyramid torinder
<((II)*I)I> : Bisphone torinder
<[[II]*I]I> : Cubic bipyramid torinder
Torisphere-like:
[[III]*I] : Tesseract torisphere
((III)*I) : Torisphere
<<[II]I>*I> : Hexadecachoron torisphere
<<(II)I>*I> : Dibicone torisphere
<[III]*I> : Cubic bipyramid torisphere
[[(II)I]*I] : Cubinder torisphere
(([II]I)*I) : Dicrind torisphere
<[(II)I]*I> : Bicylindrone torisphere
[([II]I)*I] : Crindal prism torisphere
[(III)*I] : Spherinder torisphere
[<III>*I] : Octahedron prism torisphere
[<(II)I>*I] : Biconic prism torisphere
([III]*I) : Cubic crind torisphere
([(II)I]*I) : Cylindrical crind torisphere
(<III>*I) : Octahedral crind torisphere
(<(II)I>*I) : Biconic crind torisphere
<[(II)I]*I> : Bicylindrone torisphere
<([II]I)*I> : Crindal bipyramid torisphere
<(III)*I> : Bisphone torisphere
Ditorus-like:
[[[II]*I]*I] : Tesseract ditorus
(((II)*I)*I) : Ditorus
<<[II]*I>*I> : Hexadecachoron ditorus
<<(II)*I>*I> : Dibicone ditorus
<[[II]*I]*I> : Cubic bipyramid ditorus
[[(II)*I]*I] : Cubinder ditorus
(([II]*I)*I) : Dicrind ditorus
<[(II)*I]*I> : Bicylindrone ditorus
[([II]*I)*I] : Crindal prism ditorus
[((II)*I)*I] : Spherinder ditorus
[<[II]*I>*I] : Octahedron prism ditorus
[<(II)*I>*I] : Biconic prism ditorus
([[II]*I]*I) : Cubic crind ditorus
([(II)*I]*I) : Cylindrical crind ditorus
(<[II]*I>*I) : Octahedral crind ditorus
(<(II)*I>*I) : Biconic crind ditorus
<[(II)*I]*I> : Bicylindrone ditorus
<([II]*I)*I> : Crindal bipyramid ditorus
<((II)*I)*I> : Bisphone ditorus
Spheritorus-like:
[[II]*II] : Tesseract spheritorus
((II)*II) : Spheritorus
<[II]*II> : Hexadecachoron spheritorus
[(II)*II] : Cubinder spheritorus
[[II]*(II)] : Cubinder antispheritorus
([II]*II) : Dicrind spheritorus
((II)*[II]) : Dicrind antispheritorus
<(II)*II> : Dibicone spheritorus
<[II]*(II)> : Dibicone antispheritorus
[(II)*(II)] : Duocylinder spheritorus
([II]*[II]) : Duocrind spheritorus
<(II)*(II)> : Duocircular tegum spheritorus
Tiger-like:
Here's a video for the cross-sections of the tiger-likes.
The tesseract tiger and hexadecachoron tiger both are interesting enough that I thought they deserved their own names, the tigeract and orthotiger.
((II)*(II)*) : Tiger
([II]*(II)*) : Dicrind tiger
([II]*[II]*) : Duocrind tiger
[(II)*(II)*] : Duocylinder tiger
[[II]*(II)*] : Cubinder tiger
[[II]*[II]*] : Tesseract tiger (Tigeract)
<(II)*(II)*> : Duocircular tegum tiger
<[II]*(II)*> : Dibicone tiger
<[II]*[II]*> : Hexadecachoron tiger (Orthotiger)
Generalizations
In bracketoratopes, we have three products for three shapes: circles, squares, and diamonds. Can we generalize this to other shapes, like triangles, hexagons, and octagons? It turns out we can! Here's a way to create an equation for any polygon:
Let L((a,b),(c,d)) be the equation of the line Ax+By=0 that passes through the points (a-c,b-d) , (0,0).
Then if p1, p2, p3, ... , pn-1, pn are the points of our polygon, our final equation for our polygon will be
- max(L(p1,p2), L(p2,p3), ... L(pn-1,pn), L(pn,p1)).
For example, we can create a triangle product using the vertices for an equilateral triangle. Simplifying this out we get tri(x,y) = max(-2y , y-x*sqrt(3) , y+x*sqrt(3)). Here's a desmos link where you can see the equations for any triangle.
More generally, if we have any function F(x,y) from reals to reals, it creates a product. The only problem with this is that you can never be sure if adjusting a radius will scale the function or not.
In particular, further investigation into the regular triangle, hexagon, and octagon products could be interesting.
Code used
In case anyone wants to try creating some visualizations themselves, I used a slightly modified version of this code to create these images and animations, with the addition of three functions:
- Code: Select all
#declare T = function { sqrt(pow(x,2)+pow(y,2)) - z }
#declare O = function { abs(x)+abs(y) - z }
#declare H = function { max(abs(x),abs(y)) - z }
These have the torus operation built into them, so you just need to set the third input to zero when rendering. I should note that the max function is pretty slow in POV-Ray, so rendering bracketoratopes containing Cartesian products will take a longer amount of time (also just a reminder to set a .ini file before rendering!).