mathgeometrycomputational-geometrygeometry-surface

Intersection of an infinite cylinder and circle in 3D space


I'm trying to determine if an infinite cylinder and circle intersect in 3D space. This has been asked here: Finding the intersection of the Circle and Infinite Cylinder in 3D space

However, only a mathematician can understand the response by Yves Daoust. There is another response by MBo, which I have coded (below). Unfortunately, testing shows that it doesn't work properly. I'm looking for help with this that a non-mathematician can understand. Thanks in advance!

// cylinderLoc = infinite cylinder location (any location on the cylinder axis)
// cylinderDir = infinite cylinder direction (normalized)
// cylinderRadius = infinite cylinder radius
// circleLoc = circle location (circle center)
// circleDir = circle direction (normalized direction of the circle plane)
// circleRadius = circle radius
bool cylinderIntersectCircle(
    Vector3 cylinderLoc, Vector3 cylinderDir, double cylinderRadius,
    Vector3 circleLoc, Vector3 circleDir, double circleRadius)
{
    // get the perpendicular distance from the circle center to the cylinder axis
    Vector3 diff = Vector3.Subtract(circleLoc, cylinderLoc);
    diff = Vector3.Cross(cylinderDir, diff);
    double distance = diff.Length(); // the length is also called the magnitude

    // get the dot product (cosine) between the cylinder and circle directions
    double dot = Vector3.Dot(cylinderDir, circleDir);

    // determine if the cylinder and circle intersect
    return (distance <= cylinderRadius + circleRadius * Abs(dot));
}

UPDATE: Here is a picture showing what might make is simpler. I need that "sweet spot" where the circle rim is deepest into the footprint that the cylinder has on the circle's plane. The direction from the circle center that takes it closest to the cylinder footprint. Cylinder / circle intersection

UPDATE 2: Here are some sample numbers for MBo to see that demonstrate his algorithm returning false when it should return true. Below it is a picture of the result. I made each object a different color to help. The camera is rotated 180 degrees for a better view (looking at the back). The green frame is "distance". The blue frame is "cylinderRadius + circleRadius * Abs(dot)".

cylinderLoc = ( 0.0, 0.0, 0.0 )
cylinderDir = ( 0.0, 1.0, 0.0 )
cylinderRadius = 0.3

circleLoc = ( -0.25, 0.0, -0.5 )
circleDir = ( -0.6, -0.5, 0.6245 )
circleRadius = 0.45
// get the perpendicular distance from the circle center to the cylinder axis
Vector3 diff = Vector3.Subtract(circleLoc, cylinderLoc);
// ---> diff = ( -0.25, 0.0, -0.5 ) - ( 0.0, 0.0, 0.0 )
// ---> diff = ( -0.25, 0.0, -0.5 )
diff = Vector3.Cross(cylinderDir, diff);
// ---> diff = cross(( 0.0, 1.0, 0.0 ), ( -0.25, 0.0, -0.5 ))
// ---> cross.x = 1.0 * -0.5  -  0.0  * 0.0   = -0.5
// ---> cross.y = 0.0 * -0.25 - -0.5  * 0.0   =  0.0
// ---> cross.z = 0.0 *  0.0  - -0.25 * 1.0   =  0.25
// ---> diff = ( -0.5, 0.0, 0.25 ));
double distance = diff.Length(); // the length is also called the magnitude
// ---> distance = Sqrt(-0.5 * -0.5 + 0.0 * 0.0 + 0.25 * 0.25)
// ---> distance = Sqrt(0.25 + 0.0 + 0.0625)
// ---> distance = Sqrt(0.3125)
// ---> distance = 0.55901699437494742410229341718282 (0.559 is close enough)

// get the dot product (cosine) between the cylinder and circle directions
double dot = Vector3.Dot(cylinderDir, circleDir);
// ---> dot = dot((0.0, 1.0, 0.0), (-0.6, -0.5, 0.6245))
// ---> dot = 0.0 * -0.6 + 1.0 * -0.5 + 0.0 * 0.6245
// ---> dot = -0.5

// determine if the cylinder and circle intersect
return (distance <= cylinderRadius + circleRadius * Abs(dot));
// ---> return (0.559 <= 0.3 + 0.45 * Abs(-0.5));
// ---> return (0.559 <= 0.525);
// ---> This returns false, but the circle does in fact intersect the cylinder.

enter image description here


Solution

  • A picture says a thousand words. This is what I have come up with for now. It's not 100% perfect, but it's pretty close. The magenta dots in the picture can all be calculated, meaning that the yellow lines can be calculated. Simply see if the yellow line intersects the cylinder, which is easy to do.

    enter image description here