slavfox.space:~\$
back to posts

Building procedural revolver cylinders for fun and profit

Mon Aug 12, 2019 · 1671 words · 9 min

I’m on vacation, which means I jump on any fun side project I can think of. Having just gotten a VR headset, I was playing Hot Dogs, Horseshoes and Hand Grenades when I started pondering the geometry of revolver cylinders. I quickly decided it’d be cool to implement a system that can generate a 3D model of a cylinder of any given size and chamber number. That’s what I’m going to talk about today.

This is what we’ll be making:

The constraints

Let’s start by defining some constraints. A cylinder of radius 1 with chambers of radius 100 doesn’t make sense, so our system needs to take that into account.

Our cylinder is going to look something like this:

Where:

• $$A$$ is the center of the cylinder
• $$R$$ is the radius of the cylinder
• $$Rc$$ is the radius of a single chamber (half of the caliber)
• $$n$$ is the number of chambers (in this example, 6)

We want to make sure that:

1. The outer wall of the chamber ($$\lvert DE \rvert$$) has a reasonable thickness.
2. The walls between consecutive chambers ($$\lvert FG \rvert$$) have a reasonable thickness.

Looking around, I found this document, indicating that a good ballpark for minimum chamber wall thickness would be somewhere around a third of the chamber diameter - we’re looking for an $$R$$ such that $$\lvert DE \rvert > \frac{2}{3}Rc$$.

Let’s start with the first constraint. We can easily see that $$\lvert DE \rvert = \frac{R}{2} - 2Rc$$. Shuffling the terms around gives:

$$\lvert DE \rvert > \frac{2}{3}Rc ⇔ R > \frac{16}{3}Rc$$

That’s our answer for the first constraint. Simple enough!

How about the other constraint? We can see in the image that $$\lvert FG \rvert = \lvert CC’ \rvert - 2Rc$$. Although the triangle $$\triangle ACC’$$ in the image is equilateral, this is only the case for $$n=6$$, so we cannot make use of that. However, we know the angle $$\alpha$$, and that will come in especially handy. The law of cosines gives us:

$$\lvert CC’ \rvert ^2 = \lvert AC \rvert ^2 + \lvert AC’ \rvert ^2 - 2( \lvert AC \rvert \lvert AC’ \rvert ) \cos \alpha$$

Knowing that $$\lvert AC \rvert = \lvert AC’ \rvert = \frac{R}{2} + Rc$$, and $$\alpha = \frac{2 \pi}{n}$$:

$$\lvert CC’ \rvert ^2 = 2(\frac{R}{2} + Rc)^2(1 - \cos \frac{2 \pi}{n})$$

Let’s call the part with the cosine $$x$$:

$$x = (1 - \cos \frac{2 \pi}{n}) \\ \lvert CC' \rvert ^2 = 2x(\frac{R}{2} + Rc)^2 \\ \lvert FG \rvert = \sqrt{2x(\frac{R}{2} + Rc)^2} - 2Rc$$

For $$\lvert FG \rvert$$ to be greater than or equal to $$\frac{2}{3}Rc$$:

\begin{align*} \sqrt{2x(\frac{R}{2}+Rc)^2} - 2Rc & \geq \frac{2}{3}Rc \\ 3 \sqrt{2x(\frac{R}{2}+Rc)^2} & \geq 8Rc \\ 3 \sqrt{2x}(\frac{R}{2}+Rc) & \geq 8Rc \\ \sqrt{2x}(R + 2Rc) & \geq \frac{16}{3}Rc \end{align*}

As an example, let’s try six chambers:

\begin{align} x & = (1 - \cos (\frac{2 \pi}{6})) \\ & = (1 - \frac{1}{2}) \\ & = \frac{1}{2} \end{align}

\begin{align} \lvert FG \rvert & \geq \frac{2}{3}Rc \\ \sqrt{2x}(R + 2Rc) & \geq \frac{16}{3}Rc \\ 1(R+2Rc) & \geq \frac{16}{3} Rc \\ R & \geq \frac{10}{3} Rc \end{align}

Let’s try nine chambers!

\begin {align} x & = (1 - \cos (\frac{2 \pi}{9})) \\ x & \approx (1 - 0.766044...) \\ x & \approx 0.234 \end {align}

\begin {align} \sqrt{0.468}(R + 2Rc) & \geq \frac{16/3}Rc \\ 0.6841(R + 2Rc) & \geq \frac{16/3}Rc \\ R & \geq 5.79606 Rc \end {align}

So, for nine chambers, our $$R$$ should be at least $$5.79606Rc$$.

Getting into the groove

Revolver cylinders often have a notable feature we’re forgetting here - the grooves cut between chambers on the outside. Let’s figure out how to do the other side of the cylinder, where the grooves sit!

This is how the result should look:

We’re going to cut circles that intersect the cylinder at right angles into it halfway between each pair of chambers. Here’s what’s new:

• The first thing we can see is that I’m using a five-chamber cylinder as the example for this section, since it’s easier to see that $$N$$ lies outside of the cylinder.
• $$K$$ is the midpoint of $$CC’$$. This also means that $$AK$$ bisects the angle $$\alpha$$.
• $$I$$ is the midpoint of $$C’K$$. Note that this is a complete asspull - if we wanted to have wider grooves, we’d pick a point that’s closer to $$C’$$, if we wanted narrower grooves we’d pick a point that’s closer to $$K$$. I feel like choosing the midpoint of $$C’K$$ gives good results here.
• $$L$$ is the intersection of the line $$AI$$ with the cylinder.
• $$N$$ lies at the intersection of the line $$AK$$ and the tangent to the cylinder that passes through $$L$$.
• Our groove is a circle with center $$N$$ and radius $$Rn$$
• $$\lvert C’M \rvert = \lvert CE \rvert$$

We want to find $$\lvert AN \rvert$$ and $$Rn$$.

Let’s start by finding $$\lvert C’K \rvert$$.

\begin {align} \lvert C'K \rvert & = \frac{ \lvert CC' \rvert }{2} \\ & = \frac{\sqrt{2x(\frac{R}{2} + Rc)^2}}{2} \\ & = \frac{\sqrt{2x} ( \frac{R}{2} + Rc)}{2} \\ \end {align}

Noticing that $$\triangle AKC’$$ and $$\triangle AKI$$ are right-angled, we can find the angle $$\angle AKI$$ if we know $$\lvert AK \rvert$$. Let’s do that real quick, with the help of our friend Pythagoras.

\begin {align} \lvert AK \rvert & = \sqrt{\lvert AC' \rvert ^2 + \lvert C'K \rvert ^2} \\ & = \sqrt{(\frac{R}{2} + Rc)^2 + (\frac{\sqrt{2x} (\frac{R}{2} + Rc)}{2})^2} \\ & = \sqrt{(\frac{R}{2} + Rc)^2 + \frac{x(\frac{R}{2} + Rc)^2}{2}} \\ & = \sqrt{\frac{x + 2}{2}(\frac{R}{2} + Rc)^2} \\ & = \sqrt{\frac{x + 2}{2}}(\frac{R}{2} + Rc) \\ \end {align}

\begin {align} \lvert AI \rvert & = \sqrt{\lvert AK \rvert ^2 + \lvert IK \rvert ^2} \\ & = \sqrt{\lvert AK \rvert ^2 + (\frac{\lvert C'K \rvert}{2}) ^2} \\ & = \sqrt{\frac{x + 2}{2}(\frac{R}{2} + Rc)^2 + (\frac{\frac{\sqrt{2x} ( \frac{R}{2} + Rc)}{2}}{2})^2} \\ & = \sqrt{\frac{x + 2}{2}(\frac{R}{2} + Rc)^2 + \frac{1}{8}x( \frac{R}{2} + Rc)^2} \\ & = \sqrt{\frac{5x + 8}{8}(\frac{R}{2} + Rc)^2} \\ & = \frac{\sqrt {5x + 8}}{2 \sqrt 2}(\frac{R}{2} + Rc) \\ \end {align}

\begin {align} \cos \angle IAK & = \frac{\lvert AK \rvert}{\lvert AI \rvert} \\ & = \frac{ \sqrt{\frac{x+2}{2}}(\frac{R}{2} + Rc) }{ \frac{\sqrt{5x+8}}{2 \sqrt{2}} (\frac{R}{2} + Rc) } \\ & = \frac{ \sqrt{\frac{x+2}{2}} }{ \frac{\sqrt{5x+8}}{2 \sqrt{2}} } \\ & = \frac{2\sqrt{x+2}}{\sqrt{5x+8}} \\ \end {align}

Knowing that $$\angle ANL = \frac{ \pi }{2} - \angle IAK$$ we can finally look for $$\lvert AN \rvert$$ and $$Rn$$. From the law of sines:

\begin {align} \lvert AN \rvert & = \frac{R}{\sin \angle ANL} \\ & = \frac{R}{sin(\frac { \pi }{2} - \angle IAK)} \\ & = \frac{R}{cos(\angle IAK)} \\ & = \frac{R}{\frac{2\sqrt{x+2}}{\sqrt{5x+8}}} \\ & = \frac{R\sqrt{5x+8}}{2\sqrt{x+2}} \\ \end {align}

Now for $$\lvert C’N \rvert$$. Law of cosines:

\begin {align} \lvert C'N \rvert & = \sqrt{ \lvert AN \rvert ^2 + \lvert AC' \rvert ^2 - 2 \lvert AN \rvert \lvert AC' \rvert \cos \angle C'AK } \\ & = \sqrt{ \lvert AN \rvert ^2 + \lvert AC' \rvert ^2 - 2 \lvert AN \rvert \lvert AC' \rvert \cos \frac{\pi}{n} } \\ & = \sqrt{ (\frac{R\sqrt{5x+8}}{2\sqrt{x+2}})^2 + (\frac{R}{2} + Rc)^2 - 2\frac{R\sqrt{5x+8}}{2\sqrt{x+2}}(\frac{R}{2}+Rc)\cos \frac{\pi}{n} }\\ \end {align}

\begin {align} Rn & = \lvert C'N \rvert - Rc - \lvert DE \rvert \\ & = \lvert C'N \rvert - Rc - (\frac{R}{2} - 2Rc) \\ & = \lvert C'N \rvert + Rc - \frac{R}{2} \\ & = \sqrt{ (\frac{R\sqrt{5x+8}}{2\sqrt{x+2}})^2 + (\frac{R}{2} + Rc)^2 - 2\frac{R\sqrt{5x+8}}{2\sqrt{x+2}}(\frac{R}{2}+Rc)\cos \frac{\pi}{n} } + Rc - \frac{R}{2} \end {align}

What have we learned

This all looks very scary, but it’s pretty quick to do in code. But what does it actually mean?

For a cylinder with $$n$$ chambers, every $$\frac{\pi}{n}$$ radians we alternately:

1. Cut out a circle of radius $$Rc$$,
$$\lvert AC \rvert = \frac{R}{2} + Rc$$ away from the center of the cylinder - these are the chambers.
2. Cut out a circle of radius $$Rn$$, $$\lvert AN \rvert$$ away from the center of the cylinder - these are the grooves running down the sides of the cylinder.

You can find an example implementation in the source code for this page’s demo! Next week we’ll look into how to turn this into a three-dimensional model.