4
$\begingroup$

I have this code:

Show[ContourPlot3D[{y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8},
  Mesh -> {Range[-4, 6], Range[-9, 1], Range[-2, 8]},
  Axes -> True, AxesLabel -> {x, y, z},
  Ticks -> {Range[-4, 6, 1], Range[-9, 1, 1], Range[-2, 8, 1]}
  ],
 ParametricPlot3D[{3 Cos[φ] + 1, 0, 3 Sin[φ] + 3}, {φ, 
   0, 2 π},
  PlotStyle -> {Thickness[.02], Red}],
 Graphics3D[{Sphere[{1, -4, 3}, 5]}],
 ViewPoint -> {5, 5, 5}]

Which produces this image.

my plot

I have a couple of questions.

  1. The intersection of the sphere with center at $(1,-4,3)$ and radius $5$ with the $xz$ plane is a circle with equation $(x-1)^2+(z-3)^2=9$. I parametrized the circle as $x=3\cos\phi+1$, $y=0$, and $z=3\sin\phi+3$, then used ParametricPlot3D to add it to my picture. Anybody have a simple way of plotting the circle without my parametrization?

  2. How can I add my circle so it looks like a tube?

$\endgroup$
5
$\begingroup$
cf[x_, y_, z_] := Plus @@ (({x, y, z} - {1, -4, 3})^2);
opts = {ViewPoint -> {5, 5, 5}, Axes -> True, AxesLabel -> {x, y, z}, 
   Ticks -> {Range[-4, 6, 1], Range[-9, 1, 1], Range[-2, 8, 1]}, ImageSize -> 300};

BoundaryStyle

Use BoundaryStyle->{{1,2}->Directive[Red, Tube@@#&]} (or BoundaryStyle -> {{1, 2} -> Directive[Red, # /. Line -> Tube &]}) to make the boundary between the sphere and the plane rendered as a red tube.

cp = ContourPlot3D[{cf[x, y, z]== 25,  y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle -> {Directive[Blue, Opacity[0.5]], Directive[Pink, Opacity[0.5]]}, 
  BoundaryStyle -> {1 -> None, 2 -> None, {1, 2} -> Directive[Red, Tube @@ # &]}, 
  Mesh -> None, Evaluate@opts]

Mathematica graphics

cp2 = ContourPlot3D[{y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle ->None, Mesh -> {Range[-4, 6], Range[-9, 1], Range[-2, 8]}];

Show[cp, cp2]

Mathematica graphics

MeshFunctions

cp3 = ContourPlot3D[cf[x, y, z] == 25, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle -> Opacity[.5, Blue], 
  MeshFunctions -> {Function[{x, y, z}, y]}, Mesh -> {{0}}, 
  MeshStyle -> Directive[Red, Tube @@ # &], Evaluate@opts]

or MeshStyle -> Directive[Red, # /. Line -> Tube &], gives

Mathematica graphics

cp4 = ContourPlot3D[{y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle -> Opacity[.5, Red], 
  Mesh -> {Range[-4, 6], Range[-9, 1], Range[-2, 8]}];

Show[cp3, cp4]

Mathematica graphics

Notes: Two undocumented tricks are used in the above methods. The BoundaryStyle trick first appeared on this site in this answer by Daniel Lichtblau linked by @Guesswhoitis in the comments. It also features a second undocumented trick: using functions as style directives. On this second trick see this page for relevant links.

Post-processing

Alternatively, you can post-process the ContourPlot3D output to change Line to Tube.

ContourPlot3D[{cf[x, y, z] == 25, y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle -> {Directive[Blue, Opacity[0.5]], Directive[Pink, Opacity[0.5]]}, 
  Mesh -> None, BoundaryStyle -> {1 -> None, 2 -> None, {1, 2} -> Red}, 
  Evaluate@opts] /. Line -> Tube

ContourPlot3D[cf[x, y, z] == 25, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
  ContourStyle -> Opacity[.5, Blue], MeshFunctions -> {Function[{x, y, z}, y]}, 
  Mesh -> {{0}}, MeshStyle -> Red, Evaluate@opts] /. Line -> Tube

to get the same pictures as above.

Update:

How would you use this code to make the tube larger?

This is easiest with the post-processing approach: simply change /. Line->Tube to /. Line -> (Tube[#, .3]&).

With the first and second approaches, I expected that Directive[Red, Tube[#, .3]& @@ # &] would work, but it doesn't. However, Directive[Red, Module[{tt = Tube[#, .3] &}, tt @@ # &]] works. It seems that, somehow, with another layer of function evaluation it gets too deep for Directive to process the primitive properly.

Alternatively, you can define a tube primitive function tubeF outside, and use it inside Directive:

ClearAll[tubeF]
tubeF[col_: Red, rad_: .1] := Module[{tf = Tube[#, rad] &}, Directive[col, tf @@ # &]];

Row[ContourPlot3D[{cf[x, y, z] == 25, y == 0}, {x, -4, 6}, {y, -9, 1}, {z, -2, 8}, 
    ContourStyle -> {Directive[Blue, Opacity[0.5]], Directive[Pink, Opacity[0.5]]},
    BoundaryStyle -> {1->None, 2->None, {1, 2}->#}, Mesh -> None, Evaluate@opts] & /@ 
 {tubeF[], tubeF[Orange, .3], tubeF[Purple, .5]}]

enter image description here

Row[ContourPlot3D[cf[x, y, z] == 25, {x, -4, 6}, {y, -9, 1}, {z, -2, 8},
    ContourStyle -> Opacity[.5, Blue], MeshFunctions -> {Function[{x, y, z}, y]}, 
    Mesh -> {{0}}, MeshStyle -> #, Evaluate@opts] & /@
  {tubeF[], tubeF[Orange, .3], tubeF[Purple, .5]}]

enter image description here

$\endgroup$
  • $\begingroup$ First time I've seen something like: BoundaryStyle -> {1 -> None, 2 -> None, {1, 2} -> Directive[Red, Tube @@ # &]}. I'm assuming that 1 means the first contour, 2 means the second contour, and {1,2} means the intersection of the first and second contours. Where is this explained in the documentation? I went to BoundaryStyle, but did not find an example of this. $\endgroup$ – David May 23 '15 at 2:43
  • $\begingroup$ A second question regarding Tube @@ # &. Now, I looked up @@ for the fiftieth time and it replaces the head of expression by Tube. What is the head of the expression before it is replaced with Tube? Is there some sort of minimal example that would explain this? $\endgroup$ – David May 23 '15 at 2:53
  • $\begingroup$ @David. thank you the accept. As you discovered it is an undocumented trick. I updated with links to relevant answers that used the two undocumented methods. Re Tube@@#&, in this case, it replaces Line with Tube. See also the examples here. $\endgroup$ – kglr May 23 '15 at 8:29
  • $\begingroup$ How would you use this code to make the tube larger? I have read an example in the documentation: Graphics3D[Tube[{{0, 0, 0}, {1, 1, 1}}, .1]]. But if I use Directive[Red, Tube @@ # &], how do I add the size increase? $\endgroup$ – David May 24 '15 at 0:45
  • $\begingroup$ @David, Defining tube = Tube[#, .3] & before ContourPlot3D is invoked and using Directive[Red, tube @@ # &] or Directive[Red, # /. Line -> tube &] works. (I thought Directive[Red, Tube[#, .3]& @@ # &] would work, but it doesn't.) $\endgroup$ – kglr May 24 '15 at 10:57
4
$\begingroup$

Just using a slightly different approach and using the derived circle and interpreting question as generating a torus from the circle of intersection between sphere and x-z plane:

s = ParametricPlot3D[
   5 {Sin[u] Cos[v], Sin[u] Sin[v], Cos[u]} + {1, -4, 3}, {u, 0, 
    Pi}, {v, 0, 2 Pi}, 
   RegionFunction -> Function[{x, y, z, u, v}, y <= 0], Mesh -> None];
t[r_, p_, b_] := 
  ParametricPlot3D[
   p + b {Cos[u], 0, Sin[u]} + 
    r Cos[v] {Cos[u], 0, Sin[u]} + {0, r Sin[v], 0}, {u, 0, 
    2 Pi}, {v, 0, 2 Pi}, Mesh -> False, PlotStyle -> Red];
Manipulate[
 Show[s, t[r, {1, 0, 3}, 3], Boxed -> False, Axes -> False, 
  Background -> Black, PlotRange -> All], {r, Range[0.05, 0.5, 0.05]}]

enter image description here

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.