
1. Mathematics
We want to find the intersections of
-
A ray starting at point \(O\) and having direction \(\vec\Delta\).
-
An infinitely long cylinder with radius \(R\). We choose the cylinder to be aligned with the Z-axis.
A cylinder can be seen as an infinite number of circles stacked upon each other. To find the intersections, we temporarily get rid of the Z-dimension, which reduces the problem to 2D space in which we need to find the intersection of a ray with a circle. We thus have
-
A ray starting at point \(O' = (O_\mathrm{x}, O_\mathrm{y})\) where \(O_x\) and \(O_y\) are the x- and y-coordinates of the original ray’s origin \(O\). The ray’s direction is \(\vec\Delta' = (\vec\Delta_\mathrm{x}, \vec\Delta_\mathrm{y})\).
-
A circle centered at \((0, 0)\) with radius \(R\).
A circle is defined as the set of all points \(P\) at a distance \(R\) from a given center (in our case, \((0, 0)\).) \(P\) must therefore satisfy the following equation:
The distance can be expressed using the dot product:
Squaring both sides gets rid of the square root:
\(P\) must also lie on the ray, which means it must also satisfy
Combining both equations, we get
Expanding and rearranging yields
We simplify this equation by introducing
which turns the equation to
This is a standard quadratic equation:
-
Compute the discriminant:
\[D = b^2 - 4 \cdot a \cdot c\] -
If \(D < 0\), the ray does not intersect with the circle, and hence neither does it intersect the cylinder.
-
If \(D \geq 0\), there are two intersections with \(t\)-values
\[t_1 = \frac{-b-\sqrt{D}}{2 \cdot a} \qquad t_2 = \frac{-b+\sqrt{D}}{2 \cdot a}\]
\(t_1\) and \(t_2\) tell us where in 2D space the ray hits the circle. We can restore the Z-dimension and find out the 3D-intersections:
The normal at position \(P\) is
2. Summary
Given
-
A ray starting at point \(O = (O_\mathrm{x}, O_\mathrm{y}, O_\mathrm{z})\) and having direction \(\vec\Delta = (\vec\Delta_\mathrm{x}, \vec\Delta_\mathrm{y}, \vec\Delta_\mathrm{z})\).
-
A infinitely long cylinder with radius \(R\) around the Z-axis.
The intersections can be found using the following steps:
-
Compute \(O' = (O_\mathrm{x}, O_\mathrm{y})\).
-
Compute \(\vec\Delta' = (\vec\Delta_\mathrm{x}, \vec\Delta_\mathrm{y})\).
-
Solve the quadratic equation
\[ (\vec\Delta' \cdot \vec\Delta') \cdot t^2 + (2 \cdot (O' - (0,0)) \cdot \vec\Delta') \cdot t + (O' - (0,0)) \cdot (O' - (0,0)) - R^2\] -
If the quadratic equation has no solutions, the ray does not intersect the cylinder and the algorithm ends here.
-
Call the two solutions \(t_1\) and \(t_2\).
-
The hit positions can be found using
\[P_1 = O + \vec\Delta \cdot t_1 \qquad P_2 = O + \vec\Delta \cdot t_2\] -
The normal at an intersection point \(P = (P_\mathrm{x}, P_\mathrm{y}, P_\mathrm{z})\) is
\[\vec{N} = (\frac{P_\mathrm{x}}{R}, \frac{P_\mathrm{y}}{R}, 0)\]