2

Edit: This question has very useful answers, but none address how to work with spherical coordinates.


I want to plot a 2D disk in 3D space, angled perpendicular to a given direction. That direction is given by $\theta$ and $\phi$ in spherical coordinates (where $\theta$ is polar and $\phi$ is azimuthal cause I'm a physicist, sorry math people!).

Here's four approaches I've tried that nearly work but not quite:

  1. ContourPlot3D in cartesian coordinates

    ContourPlot3D[{x + y + z == 1}, {x, -2, 2}, {y, -2, 2}, {z, -2, 2}]
    

    This gives an inclined plane, but I can't figure out how to put it at the desired angles $\theta$ and $\phi$. I also wouldn't know how to make this a disk with a finite radius.

    enter image description here

  2. ContourPlot3D in spherical coordinates, by converting x+y+z==1 into spherical

    ContourPlot3D[{r*Sin[θ]*Cos[ϕ] + r*Sin[θ]*Sin[ϕ] 
         + r*Cos[θ] == 1},
    {r, 0, 1}, {θ, 0, Pi}, {ϕ, 0, 2*Pi}, AxesLabel -> Automatic]
    

    This uses {r,$\theta$,$\phi$} as the plot coordinates, rather than plotting in proper cartesian space.

    enter image description here

  3. ParametricPlot3D to make a disk, then rotate it

    ParametricPlot3D[{r*Sin[Pi/2]*Cos[ϕ],r*Sin[Pi/2]*Sin[ϕ], r*Cos[Pi/2]},
      {r, 0, 1}, {ϕ, 0, 2*Pi}, 
     PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}, AxesLabel -> {x, y, z}]
    

    This can produce a disk, but I can't figure out how to angle it. Here I set $\theta$=$\pi$/2 to make the disk.

    enter image description here

  4. Use Disk with Graphics3D and Rotate

    This would work if Disk could be used as a 3D object! Argh!


That's all my ideas. If you see how to fix one of these, or have another, better idea, please advise!

Max
  • 1,050
  • 6
  • 14
  • 2
    Some of the techniques used to create a 3D circle are certainly relevant for creating a 3D disk, but I don't think that makes this question a duplicate, especially since what I consider the best answer to that question uses BSplineCurve, and a BSplineCurve is not capable of creating a disk. I just created a resource function Disk3D based on BSplineSurface that can create a 3D disk, so I think it makes sense to reopen this question. – Carl Woll Dec 16 '19 at 22:41

3 Answers3

3

Given the normal vector

n={Cos[\[Theta]] Cos[\[CurlyPhi]], Cos[\[Theta]] Sin[\[CurlyPhi]],Sin[\[Theta]]}

the plane orthogonal to n is given by

e={Sin[\[CurlyPhi]], -Cos[\[CurlyPhi]], 0}
f={-Cos[\[CurlyPhi]] Sin[\[Theta]], -Sin[\[Theta]] Sin[\[CurlyPhi]],Cos[\[Theta]]}

The 3D-disk can be plotted using

Block[{\[Theta] = 50 \[Degree], \[CurlyPhi] = 10 \[Degree] },
Show[{Graphics3D[{Point[{0, 0, 0}], Opacity[.2], Sphere[]}], 
ParametricPlot3D [r (Cos[t] e + Sin[t] f), {r, 0, 1}, {t, 0, 2 Pi}]}, Boxed-> False]
]

enter image description here

Ulrich Neumann
  • 53,729
  • 2
  • 23
  • 55
  • Nothing wrong with you answer, but @anderstood built upon one of my solutions which made it easier for me to work with. Small feedback: aren't your n and e defined the same? – Max Feb 17 '18 at 00:10
  • Sorry, cut &paste error: I edited my answer. – Ulrich Neumann Feb 17 '18 at 14:00
  • ... n!=e: By the way I didn't agree, that using a RotationMatrix is easier than the evaluation of two orthogonal vectors... – Ulrich Neumann Feb 17 '18 at 14:07
3

First, define the normal in spherical coordinates:

n[theta_, phi_] := {Sin[theta]*Cos[phi], Sin[theta]*Sin[phi], Cos[theta]}

Then multiply your (syntax-corrected) ParametricPlot3D with RotationMatrix and wrap it in Manipulate:

Manipulate[
  Show[
     ParametricPlot3D[
       RotationMatrix[{{0, 0, 1}, n[theta, phi]}].  
         {r*Sin[Pi/2]*Cos[Phi], r*Sin[Pi/2] Sin[Phi], r*Cos[Pi/2]}
         , {r, 0, 1}, {Phi, 0, 2*Pi}
         , PlotRange -> {{-1, 1}, {-1, 1}, {-1, 1}}
         , AxesLabel -> {x, y, z}]
      , Graphics3D[{Red, Arrow[{{0, 0, 0}, n[theta, phi]}]}]]
  , {theta, 0, 2 Pi}, {phi, 0, Pi}]

enter image description here

anderstood
  • 14,301
  • 2
  • 29
  • 80
  • This is beautiful, thank you. RotationMatrix was the missing piece to my idea #3 above. Small note: typically theta goes 0->Pi and phi goes 0->2Pi. – Max Feb 17 '18 at 00:04
3

The resource function Disk3D generates a BSplineSurface representation of a 3D disk. For example, a 3D disk with symmetry axis in the direction {1, 1, 1}:

Graphics3D @ ResourceFunction["Disk3D"][{0,0,0}, 1, {1, 1, 1}]

enter image description here

A 3D elliptical disk in the plane spanned by {1, 1, 0} and {0, 1, 1} with the semimajor axis in the direction {1, 1, 0}:

Graphics3D[{
    ResourceFunction["Disk3D"][{0, 0, 0}, {3, 1}, {{1, 1, 0}, {0, 1, 1}}], 
    Red, Arrow[{{0,0,0}, {1,1,0}}],
    Blue, Arrow[{{0,0,0}, {0,1,1}}]
}]

enter image description here

A graphic with many disks:

Graphics3D[{
    LightGreen,
    MapThread[
        ResourceFunction["Disk3D"],
        {RandomReal[10, {300, 3}], RandomReal[3, 300], RandomReal[1, {300, 3}]}
    ]
}]

enter image description here

An example of the BSplineSurface primitive:

ResourceFunction["Disk3D"][{0,0,0}]

BSplineSurface[{{{-1, 0, 0}, {-1, -1, 0}, {0, -1, 0}}, {{-1, 1, 0}, {1/9, 0, 0}, {1, -1, 0}}, {{0, 1, 0}, {1, 1, 0}, {1, 0, 0}}}, SplineKnots -> {{0, 0, 0, 1, 1, 2}, {0, 0, 0, 1, 1, 2}}, SplineWeights -> {{1, 1/Sqrt[2], 1}, {1/Sqrt[2], 1, 1/Sqrt[2]}, {1, 1/Sqrt[2], 1}}]

Carl Woll
  • 130,679
  • 6
  • 243
  • 355