2
$\begingroup$

I have a given point in space (Point C in Figure) and a cylinder, defined by its start/end center points and radius. I have a point on the axis (Point D), and I need to find the intersection between the cylinder and the line for CD. I also know Point C is in between the two ends of the cylinder, to simplify the solution. What's the easiest way to calculate point H? My idea is to calculate the closest point from C on the cylinder axis (Point E), then calculate point G and obtain point H from trigonometry exploiting the triangles similitude. But it seems too tricky. Any better idea? My code would look like:

E = D - dot(CD,u_v) * u_v1
G = E + radius * u_v2
H = G + u_v1 * CG * tan(alfa)

where u_v1 is the unit vector for the axis of the cylinder, u_v2 is the unit vector of the EC direction and alfa is the angle CE forms with CD.

Cylinder-Line_Intersection

1 Answers 1

0

I don’t think that you need to compute any angles or (explicitly) normalize vectors to solve this, although you do end up computing a vector length or two. My approach to this problem seems similar to yours: First, find the orthogonal projection of the vector $C-D$ onto a plane that’s perpendicular to the cylinder’s axis. Once you have this projection, find the scale factor that changes its length to $r$ (the cylinder’s radius) and multiply $C-D$ by this same factor.

The orthogonal projection of a vector onto the perpendicular plane is the same as its orthogonal rejection from the axis, so letting $A$ be one of the end points of the cylinder axis, this would be $$\mathbf v=(C-D)-{(C-D)\cdot(A-D)\over(A-D)\cdot(A-D)}(A-D).$$ The required scale factor is $\frac r{\|\mathbf v\|}$, so the potential intersection point is $$P=D+\frac r{\|\mathbf v\|}(C-D).\tag{1}$$ (I write “potential” here because you’d still need to verify that this point is actually on the cylinder, although if both $C$ and $D$ are “between” the end caps, this is guaranteed.)

Observe that we don’t really need $\mathbf v$ itself, but only its length. We know that $\|\mathbf v\|=\|C-D\|\sin\theta$, where $\theta$ is the angle that $C-D$ makes with the cylinder’s axis. This suggests using a cross product since $$\|(C-D)\times(A-D)\|=\|C-D\|\|A-D\|\sin\theta,$$ so $$\|\mathbf v\|={\|(C-D)\times(A-D)\|\over\|A-D\|}.$$ Substituting this into (1) gives $$P=D+r{\|A-D\|\over\|(C-D)\times(A-D)\|}(C-D)\tag{2}$$ as an alternative formula for the intersection point.

I don’t know if that’s any simpler or more efficient than your approach, but it does avoid using trigonometric functions and their inverses, and requires at most the same number of square roots as computing two unit vectors.

  • 0
    This is actually much better than mine, especially because you do not compute angles (always tricky when implementing code). Thanks a lot!2017-02-03
  • 0
    I am just thinking, this will not work if point D is coincident with the starting point of the cylinder. That means I should perform a check wether the current point is one of the two ends of the cylinder and use the other end for that case?2017-02-03
  • 0
    @ronwelty Absolutely right. Any vector parallel to the axis will work.2017-02-04
  • 0
    @ronwelty So, even better, use the difference between the cylinder’s endpoints instead of $A-D$. Then, there’s nothing to check.2017-02-04
  • 0
    Great, thanks a lot!2017-02-05