Message Boards Message Boards

"Filled in" ParametricPlot3D?

GROUPS:

Hello all! I'm currently finding my way through Mathematica (novice here), and am having issues "filling in" a Parametric3DPlot, as shown below:

ParametricPlot3D[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[t], u}, 
{t, 0, 2 Pi}, {u, 0, 1}, Mesh -> None, PlotStyle -> Opacity[.9]]

While these "petals" somewhat work, how do I fill them in, to make them a solid shape? Thanks!

POSTED BY: David Joseph
Answer
20 days ago

Here is a way:

f[t_, u_, r_] = {r (1 + Cos[(8 t)]) Cos[t], r (1 + Cos[8 t]) Sin[t], 
   u};
Show[ParametricPlot3D[f[t, u, 1], {t, 0, 2 Pi}, {u, 0, 1}, 
  Mesh -> None, PlotStyle -> Opacity[.9], PlotPoints -> {40, 2}],
 ParametricPlot3D[{f[t, 1, r], f[t, -1, r]}, {t, 0, 2 Pi}, {r, 0, 1}, 
  Mesh -> None, PlotStyle -> Opacity[.9], PlotPoints -> {40, 2}]]
POSTED BY: Gianluca Gorni
Answer
19 days ago

The following uses the vertices of the top and bottom edges, where u is approximately one of {0, 1}. It is only approximate because ParametricPlot3D uses open sampling. The advantage to using the actually discrete edges of the graphics is that the lids "fit tightly."

ParametricPlot3D[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[t], u},
  {t, 0, 2 Pi}, {u, 0, 1},
  PlotPoints -> {120, 5},
  Mesh -> None, PlotStyle -> Opacity[0.9], 
  BoundaryStyle -> Opacity[0.9]] /.     
 GraphicsComplex[pts_, g_, opts_] :>
  GraphicsComplex[
   pts,                   (* array of coordinates of points in the graphics *)
   g /. Line[idcs_] :> {  (* points are specified by their indices in the coordinate array  pts  *)
      EdgeForm[],
      Polygon[
       SplitBy[
        Select[
         idcs,
         Min@Abs[pts[[#, 3]] - {0, 1}] < 1*^-6 &],  (* select indices at the boundary edges  {0, 1}  *)
        Nearest[{0, 1}, pts[[#, 3]]] &],      (* split the indices according to bottom, top  {0, 1}  *)
       VertexNormals -> None]     (* the polygons are virtually flat and should not inherit the VertexNormals
                                     assigned to their points on the original surface (the sides) *)
      },
   opts]

Alternatively, one can construct a cylinder given a base polygon.

base = First@Cases[
    ParametricPlot[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[t]}, {t, 0, 2 Pi}],
    Line[p_] :> p, Infinity];
RegionProduct[Polygon[base], Line[{{0.}, {1.}}]]

Or just construct the base directly with Table:

base = Most@
   Table[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[t]},
    {t, 0., 2 Pi, 2 Pi/8/100}];   (* 100 yields a sufficient sampling density *)
POSTED BY: Michael Rogers
Answer
19 days ago

Very interesting solutions! Michael, thanks, but where do you get and what is the meaning of:

Line[{{0}, {1}}] ?

I cannot find in the Line docs any such syntax for Line[].

Also,

Graphics[Line[{{0}, {1}}]]

gives the error: "Array {{0}, {1}} has the wrong dimensions for a graphics coordinate list. Am I missing something?

POSTED BY: Updating Name
Answer
16 days ago

The special syntax Line[{{0}, {1}}] is not used for 2D graphics, but for geometric regions. It means the line in 1D space, connecting the two zero-dimensional points {0} and {1}.

POSTED BY: Gianluca Gorni
Answer
16 days ago

This is so helpful, thank you all. One more question: I am trying to combine this with another ParametricPlot3D, but whenever I try the command Show[{figure1,figure2,figure3}, PlotRange->All], it returns that it cannot combine them. Any help with this part?

POSTED BY: David Joseph
Answer
19 days ago

You can also use the derived geometric region functions:

RegionProduct[
 BoundaryDiscretizeGraphics@
  ParametricPlot[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[t]},
   {t, Pi/8, 2 Pi + Pi/8}],
 DiscretizeRegion@Line[{{0}, {1}}]]
POSTED BY: Gianluca Gorni
Answer
19 days ago

@Gianluca Gorni thank you so much! One last question (sorry!): how do I change the color of this graphic? I'm confused as to where I would put it in the coding. :)

POSTED BY: David Joseph
Answer
19 days ago

Right now I cannot check with Mathematica, but you may look up MeshPrimitives, that converts a Region to Graphics3D, to which you can give color styling.

POSTED BY: Gianluca Gorni
Answer
19 days ago

@Gianluca Gorni Hm... can't seem to exactly find the right resources to convert the code you gave me into a MeshFunction. Perhaps when you get the chance you could help me. Thanks!

POSTED BY: David Joseph
Answer
19 days ago

Here is an example:

reg = RegionProduct[
   BoundaryDiscretizeGraphics@
    ParametricPlot[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[
        t]}, {t, Pi/8, 2 Pi + Pi/8}],
   DiscretizeRegion@Line[{{0}, {1}}]];
Graphics3D[{Red, EdgeForm[], MeshPrimitives[reg, 2]}]
POSTED BY: Gianluca Gorni
Answer
18 days ago

This is a ligher version, with only the boundary shown:

reg = RegionBoundary@
   RegionProduct[
    BoundaryDiscretizeGraphics@
     ParametricPlot[{(1 + Cos[(8 t)]) Cos[t], (1 + Cos[8 t]) Sin[
         t]}, {t, Pi/8, 2 Pi + Pi/8}], 
    DiscretizeRegion@Line[{{0}, {1}}]];
Graphics3D[{Red, EdgeForm[], Opacity[.5], MeshPrimitives[reg, 2]}]
POSTED BY: Gianluca Gorni
Answer
17 days ago

Group Abstract Group Abstract