Yesterday we made an algorithm that could build procedural revolver cylinders. Unfortunately, it has some quirks that I’m not too happy about - particularly, once there are enough chambers that the distance between them is smaller than the distance between a chamber and the outer wall, the cylinder starts getting unreasonably thick. We’ll fix that today, and parametrize the algorithm further, so that the generation can be tweaked even more.

I’ll split this into four parts - in the first part we’ll talk about generating the cylinder itself, in the second part we’ll be tweaking our generator to support polygonal cylinders, akin to the Chiappa Rhino, we’ll add grooves in the third post, and then make the whole thing 3D in the final chapter.

Let’s start! This is what we made last time:

The result of this part can be found at the very bottom of this post.

# The groundwork

As usual, let’s start by looking at what we want.

This time, we’ll start by defining the outer wall thickness as a third of a chamber’s radius, instead of arbitrarily making the chamber start halfway out. This will help deal with disproportionately small chambers way better.

Let’s look at our definitions real quick:

- \(A\) is the center of the cylinder
- \(R\) is the radius of the cylinder
- \(R_c\) is the radius of a single chamber (half of the caliber)
- \(n\) is the number of chambers (in this example, 6)
- \( \lvert CK \rvert = \lvert CO \rvert = \frac{4}{3}R_c\)

However, to let us parametrize the creation even more, we’ll change the arguments (\(n\), \(R_c\), and \(R\) growth) to our algorithm. Instead of \(R\) growth, which caused \(R\) to grow past the minimum value, we’ll have \(R_i\) and \(R_o\), which, respectively, will be added to the inner radius (\( AK \)), and the outer radius (\( CO \)). In total, we now have:

$$ R = \lvert AK \rvert + R_i + 2(\frac{4}{3}R_c) + R_o $$

We’ll need to find \( \lvert AC \rvert \), and we know it’s equal to \( \lvert AK \rvert + \frac{4}{3}R_c \).

Although for six chambers and \(R_i = R_o = 0\) the triangle \( \triangle AC’C \) is equilateral, this is not always the case. It is, however, an isosceles triangle, which we can use to our advantage, along with our knowledge that \( \alpha = \frac{2 \pi}{n} \).

Note that we can handwave away \(R_i\) and \(R_o\). Since our algorithm only needs to know how big the cylinder is, and how far away the chambers are, we can do all our calculations assuming \(R_i = R_o = 0\), and then just add the values afterwards. This lets us have \( \lvert CC’ \rvert = \frac{7}{3} R_c \). Armed with that knowledge, let’s finally find \( \lvert AK \rvert \)!

$$ \begin{align} \frac{\lvert AC \rvert}{\sin (\frac{\pi - \alpha}{2})} & = \frac{\lvert CC' \rvert }{\sin \alpha} \\ \frac{\lvert AK \rvert + \frac{4}{3}R_c}{\sin (\frac{\pi - \alpha}{2})} & = \frac{ \frac{7}{3} R_c }{\sin \alpha} \\ \frac{\lvert AK \rvert + \frac{4}{3}R_c}{\cos (\frac{\alpha}{2})} & = \frac{ 7 R_c }{3 \sin \alpha} \\ \frac {3 \sin \alpha (\lvert AK \rvert + \frac{4}{3}R_c)} {\cos (\frac{\alpha}{2})} & = 7 R_c \\ \frac {3 \sin \alpha}{\cos (\frac{\alpha}{2})}\lvert AK \rvert + \frac{\frac{4}{3}R_c}{\cos (\frac{\alpha}{2})} & = 7 R_c \\ \frac {3 \sin \alpha}{\cos (\frac{\alpha}{2})}\lvert AK \rvert & = 7 R_c - \frac{\frac{4}{3}R_c}{\cos (\frac{\alpha}{2})} \\ \lvert AK \rvert & = \frac{7 R_c - \frac{\frac{4}{3}R_c}{\cos (\frac{\alpha}{2})}}{\frac {3 \sin \alpha}{\cos (\frac{\alpha}{2})}} \\ & = \cos (\frac{\alpha}{2}) 7 R_c - \frac{\frac{4}{3}R_c}{ 3 \sin \alpha} \\ & = \frac{(21 \cos (\frac{\alpha}{2}) - 4) R_c}{ 9 \sin \alpha} \\ \end{align} $$

That gives us:

$$ \begin{align} \lvert AC \rvert & = \lvert AK \lvert \color{red}{+ R_i} + \frac{4}{3}R_c \\ & = \frac{(21 \cos (\frac{\alpha}{2}) - 4) R_c}{ 9 \sin \alpha} \color{red}{+ R_i} + \frac{4}{3}R_c \end{align} $$

And:

$$ \begin{align} \lvert AO \rvert & = R \\ & = \lvert AC \lvert + \frac{4}{3}R_c \color{red}{+ R_o} \\ & = (\lvert AK \lvert \color{red}{+ R_i} + \frac{4}{3}R_c) + \frac{4}{3}R_c \color{red}{+ R_o} \\ & = \frac{(21 \cos (\frac{\alpha}{2}) - 4) R_c}{ 9 \sin \alpha} \color{red}{+ R_i} + \frac{8}{3}R_c \color{red}{+ R_o} \\ \end{align} $$

Alright, cool! Let’s see how it looks. Notice that I’ve increased the maximum chamber count, since the new algorithm deals with extreme numbers much better.

As before, you can see the algorithm in the source code for this page’s demo.