2
$\begingroup$

Is there a way to find the intersection of boundaries of two cylinders without the user having to struggle with equations and, so to speak, reinvent the wheel? (I am particularly interested in intersection of infinite cylinders so that there is no problem with dealing with cylinder bases)

reg does not seem to be of any use - it can't be plotted, RandomPoint does not work on it, it produces wrong results like RegionMember giving False for point {1, 0, 1/905 (590 - Sqrt[469551])} which is in fact member of the region.

c1 = Cylinder[2 {{0, 0, -2}, {0, 0, 2}}];
c2 = Cylinder[{-2 {1, 1, 1}, 2 {1, 1 - 1/5, 1}}, 4/5];
Graphics3D[{c1, c2}]
reg=RegionIntersection @@ RegionBoundary /@ {c1, c2}

enter image description here

$\endgroup$
5
  • $\begingroup$ Since the surfaces of cylinders are two-dimensional objects, their intersection is a one-dimensional curve. I don't think Mathematica can properly handle codimension two curves in a three-dimensional space as a "region." $\endgroup$ Commented 2 days ago
  • $\begingroup$ @A.Kato What is the point of Mathematica pretending "I can handle this"? So the output of RegionIntersection should be warning/error not BooleanRegion like everything is fine. Or is there any reasonable/practical usage of such output? $\endgroup$ Commented 2 days ago
  • $\begingroup$ I don't know why it just returns BooleanRegion. This is just my guess, but it seems like Region-related functions are primarily designed for "numerical" image processing. Maybe someone will come up with a nice solution (which I also want to get), but it might be quicker to "reinvent the wheel". $\endgroup$ Commented 2 days ago
  • $\begingroup$ @A.Kato Only for the simple two dimension surfaces , the RegionIntersection work. Region[RegionIntersection[RegionBoundary@Ball[{0, 0, 0}, 1], RegionBoundary@Ball[{1, 0, 0}, 1]], PlotRange -> 1] $\endgroup$ Commented yesterday
  • $\begingroup$ @cvgmt I see, sometimes it works out well. And (+1) for your nice answer. $\endgroup$ Commented yesterday

3 Answers 3

5
$\begingroup$
  • Not the general way to do this, it is only work for the implicit equation surfaces.
  • For the RegionMember.
Clear["Global`*"];
c1 = Cylinder[2 {{0, 0, -2}, {0, 0, 2}}];
c2 = Cylinder[{-2 {1, 1, 1}, 2 {1, 1 - 1/5, 1}}, 4/5];
reg = ImplicitRegion[{x, y, z} ∈ 
     RegionBoundary@c1 && {x, y, z} ∈ RegionBoundary@c2, {x, 
    y, z}];
pt = {1, 0, 1/905 (590 - Sqrt[469551])};
{RegionMember[reg, pt], pt ∈ reg}
pts = {x, y, z} /. 
   FindInstance[{x, y, z} ∈ reg, {x, y, z}, 500];
Graphics3D[Point[pts]]

{True, True}.

enter image description here

  • For the plot, we have to define the MeshFunction from the Implicit form of such infinite cylinders.
  • We use EdgeForm[], FaceForm[] to erase the cylinder boundary and the cylinder surfaces.
(* fun = Function[{\[FormalX], \[FormalY], \[FormalZ]}, 
   SubtractSides[RegionConvert[c2, "Implicit"][[1, 2]]] // First // 
    Evaluate]; *)
fun = Function[{x, y, z}, 
   SubtractSides[RegionMember[c2, {x, y, z}] // Last] // First // 
    Evaluate];
plot = RegionPlot3D[DiscretizeRegion[c1, AccuracyGoal -> 3], 
   MeshFunctions -> fun, Mesh -> {{0}}, MeshStyle -> Thick, 
   PlotStyle -> Directive@{EdgeForm[], FaceForm[]}, Boxed -> False, Axes -> False, 
   BoundaryStyle -> None];
lines = DiscretizeGraphics[Graphics3D[Cases[Normal@plot, _Line, -1]]];
{plot, lines}
ArcLength[ConnectedMeshComponents@lines]

enter image description here

{6.16529, 6.16467}

  • Use SurfaceContourPlot3D as @lericr.
SurfaceContourPlot3D[
 SubtractSides[RegionMember[c2, {x, y, z}] // Last] // 
  First, {x, y, z} ∈ c1, Contours -> {0}, Boxed -> False, 
 Axes -> False, ContourShading -> None]

enter image description here

  • the result of SliceContourPlot3D not so good.
SliceContourPlot3D[
 SubtractSides[RegionMember[c2, {x, y, z}] // Last] // First // 
  Evaluate, RegionBoundary@c1, {x, y, z} ∈ c1, 
 Contours -> {0}, ContourShading -> None,Boxed -> False, Axes -> False]

enter image description here

$\endgroup$
3
$\begingroup$

Well, I had a thought, but I can't figure out the weird artifact.

SurfaceContourPlot3D[
  RegionDistance[c2, {x, y, z}], {x, y, z} \[Element] c1, 
  Contours -> {.0001}, 
  ColorFunction -> (Transparent &), 
  Boxed -> False, 
  Axes -> False]

enter image description here

Using just 0 instead of something near 0 didn't work. I guess I don't know enough about countour plots. Maybe it'll give you a start anyway.

An alternative that produces a thin tube rather than a line:

c1 = Cylinder[2 {{0, 0, -2}, {0, 0, 2}}, 1];
c1a = Cylinder[2 {{0, 0, -2}, {0, 0, 2}}, .99];
c2 = Cylinder[{-2 {1, 1, 1}, 2 {1, 1 - 1/5, 1}}, 4/5];
c2a = Cylinder[{-2 {1, 1, 1}, 2 {1, 1 - 1/5, 1}}, .99*4/5];

CSGRegion[
  "Intersection", 
  {CSGRegion["Difference", {c1, c1a}], CSGRegion["Difference", {c2, 2a}]}]

enter image description here

$\endgroup$
3
$\begingroup$

For high quality plotting (without knowing the exact definition of the curves) we can use ContourPlot3D.

c1 = Cylinder[{{0, 0, -4}, {0, 0, 4}}];
c2 = Cylinder[{{-2, -2, -2}, {2, 8/5, 2}}, 4/5];

{fu1, fu2} = (RegionConvert[#, "Implicit"][[1, 2]] /. 
       Thread[{\[FormalX], \[FormalY], \[FormalZ]} -> {x, y, z}] /. 
      LessEqual -> Equal) & /@ {c1, c2};

ContourPlot3D[fu1, {x, -2, 2}, {y, -2, 2}, {z, -2, 2}, 
 MeshFunctions -> 
  Function[{x, y, z}, Evaluate@First@SubtractSides@fu2], Mesh -> {{0}},
  ContourStyle -> None, BoundaryStyle -> None, PlotPoints -> 50, 
 MeshStyle -> Directive[ColorData[97, 1], Thick]]

Show[Graphics3D[{Opacity[0.5], c1, c2}], %]

enter image description here

enter image description here

If exact definition of the curves of intersection is needed:

RegionConvert[c1, "Parametric"][[1, 1]] /. 
    Thread[{\[FormalX], \[FormalY], \[FormalZ]} -> {x1, y1, z1}] /. 
   LessEqual -> Equal /. y1 -> 1;
RegionConvert[c2, "Parametric"][[1, 1]] /. 
    Thread[{\[FormalX], \[FormalY], \[FormalZ]} -> {x2, y2, z2}] /. 
   LessEqual -> Equal /. y2 -> 4/5;
%% /. Solve[%% == %, {x1, z2}, x2, Complexes]
Show[Graphics3D[{Opacity[0.5], c1, c2}], 
 ParametricPlot3D[%, {z1, -4, 2}]]

enter image description here

$\endgroup$

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.