Riddler: Magna-Tiles Polyhedra

From our friends at the Riddler:

Robert’s daughter has a set of Magna-Tiles, which, as their name implies, are tiles with magnets on the edges that can be used to build various polygons and polyhedra. Some of the tiles are identical isosceles triangles with one 30 degree angle and two 75 degree angles. If you were to arrange 12 of these tiles with their 30 degree angles in the center, they would lay flat and form a regular dodecagon. If you were to put fewer (between three and 11) of those tiles together in a similar way, they would form a pyramid whose base is a regular polygon. Robert has graciously provided a photo of the resulting pyramids when three and 11 tiles are used

If Robert wanted to maximize the volume contained within the resulting pyramid (presumably to store as much candy for his daughter as possible), how many tiles should he use?


Results

Let’s save the trig for a moment, and check out the results!

Instead of assuming that it lies flat with 12 tiles, let’s try out some other values.


Brace yourself - the trig is coming!

Brace yourself - the trig is coming!


Approach

The base

Let’s start by looking at the base of the polyhedron.

The base is a regular polygon with \(n\) sides. We can divide that regular polygon into \(n\) triangles by connecting the vertices to the center. (We’re making wedges.).

The interior angle \(\theta\) for those \(n\) triangles is \(\theta = \frac{2\pi}{n}\).


And then we can divide each triangle again in half by dropping a perpendicular from the center to the side. How long is that perpendicular, \(p\)? Well, we have basically the same equation as before, just using a different number of sides for the regular polygon.

$$ \[\begin{aligned} \tan(\tfrac{1}{2}\theta) & = (\tfrac{1}{2}a) / p \\ p & = (\tfrac{1}{2}a) \cot (\tfrac{1}{2}\theta) \\ p & = (\tfrac{1}{2}a) \cot (\frac{\pi}{n}) \end{aligned}\]

$$

The tile

Now, let’s look at the tiles that form the pyramid’s walls. For a moment, let’s imagine we had all the tiles and laid it out flat. Then the work we just did for the base can tell us the height of each tile, \(h_t\)!

We’re using \(n\) to reference how many tiles we choose to use. So we’ll use \(f\) for the number of tiles that allows us to lay the shape out flat. (In our setup, \(f = 12\).)

\[ \begin{aligned} h_t & = (\tfrac{1}{2}a) \cot (\frac{\pi}{f}) \end{aligned} \]

The wedge

With this perpendicular distance \(p\), we can get the base area of a single wedge. \[ \begin{aligned} A_w & = \tfrac{1}{2} \cdot p \cdot a \\ & = \tfrac{1}{2} \cdot (\tfrac{1}{2}a) \cot (\frac{\pi}{n}) \cdot a \\ & = \tfrac{1}{4} a^2 \cot (\frac{\pi}{n}) \end{aligned} \]

Finally 3-D time! Let’s find how tall these wedges are! With the perpendicular distance along the base \(p\), and the tile height \(h_t\) we obtained earlier, we can express the wedge height \(h_w\):

\[ \begin{aligned} h_t^2 & = p^2 + h_w^2 \\ h_w^2 & = h_t^2 - p^2 \\ & = [ (\tfrac{1}{2}a) \cot (\frac{\pi}{f})]^2 - [(\tfrac{1}{2}a) \cot (\frac{\pi}{n})]^2 \\ h_w & = \sqrt{[ (\tfrac{1}{2}a) \cot (\frac{\pi}{f})]^2 - [(\tfrac{1}{2}a) \cot (\frac{\pi}{n})]^2} \\ & = (\tfrac{1}{2}a) \sqrt{ \cot^2 (\frac{\pi}{f}) - \cot^2 (\frac{\pi}{n})} \\ \end{aligned} \]

The volume

The volume of a single wedge \(V_w\) as a function of \(n\) is given by: \[ \begin{aligned} V_w & = \tfrac{1}{3} \cdot A_w \cdot h_w \\ & = \tfrac{1}{3} \cdot [\tfrac{1}{4} a^2 \cot (\frac{\pi}{n})] \cdot [(\tfrac{1}{2}a) \sqrt{ \cot^2 (\frac{\pi}{f}) - \cot^2 (\frac{\pi}{n})}] \\ & = \frac{1}{24} \cdot a^3 \cdot \cot(\frac{\pi}{n}) \sqrt{ \cot^2 (\frac{\pi}{f}) - \cot^2 (\frac{\pi}{n})} \end{aligned} \]

And let’s not forget that we’re trying to get the total volume, \(V\): \[ \begin{aligned} V & = n \cdot V_w \\ & = n \cdot [\frac{1}{24} \cdot a^3 \cdot \cot(\frac{\pi}{n}) \sqrt{ \cot^2 (\frac{\pi}{f}) - \cot^2 (\frac{\pi}{n})}] \end{aligned} \]

The function is a little hairy. There might be some secret trig identity or limit to apply here, but let’s try just stuffing this into R’s optimize() function and see what happens.

## [1] 0.8164883

Something in the neighborhood of 81.6% of the number of tiles that lay flat seems to maximize the volume.


Code

Full code available as a RMarkdown file on Github

Calculate multiple scenarios

Summary table

# Summary for 12-tile 
options(digits = 3)
summ %>%
  filter(n_flat == 12) %>%
  select(n, h_t = tile_height, base_perp = base_center_side_dist, 
         base_wedge_area, wedge_height, wedge_volume,
         total_volume) 
## # A tibble: 10 x 7
##        n   h_t base_perp base_wedge_area wedge_height wedge_volume total_volume
##    <int> <dbl>     <dbl>           <dbl>        <dbl>        <dbl>        <dbl>
##  1     3  1.87     0.289           0.144        1.84        0.0887        0.266
##  2     4  1.87     0.5             0.25         1.80        0.150         0.599
##  3     5  1.87     0.688           0.344        1.73        0.199         0.995
##  4     6  1.87     0.866           0.433        1.65        0.239         1.43 
##  5     7  1.87     1.04            0.519        1.55        0.268         1.88 
##  6     8  1.87     1.21            0.604        1.42        0.286         2.29 
##  7     9  1.87     1.37            0.687        1.26        0.289         2.60 
##  8    10  1.87     1.54            0.769        1.06        0.271         2.71 
##  9    11  1.87     1.70            0.851        0.763       0.217         2.38 
## 10    12  1.87     1.87            0.933        0           0             0

Plot main answer

summ %>%
  filter(n_flat == 12) %>%
  ggplot(aes(n, total_volume)) +
  geom_point() +
  theme_light() +
  labs(
    title = "Polyhedra volume for n-sided regular polygon base",
    subtitle = "Assumes 12 tiles lay flat, side length = 1",
    x = "n", y = bquote("Volume" ~ (units^3))) +
    gghighlight(total_volume == max(total_volume), label_key = n,
                unhighlighted_params = list(colour = "grey60")) +
  scale_x_continuous(breaks = seq(0, 12, 2))

Optimize for maximum volume

tot_volume <- function(q, n_flat = 10000, side = 1) {
  n <- q * n_flat
  tile_height <- (side / 2 ) / tan(pi / n_flat)
  base_center_side_dist = (side / 2) / tan(pi / n)
  base_wedge_area = (1/2) * base_center_side_dist * side
  wedge_height = sqrt(tile_height ^2 - base_center_side_dist ^ 2)
  wedge_volume = (1/3) * base_wedge_area * wedge_height
  total_volume = n * wedge_volume
  return(total_volume)
}

fr_flat_tiles <- optimize(tot_volume, lower = 0, upper = 1, 
                          maximum = TRUE)$maximum
fr_flat_tiles