Removing a crease artifact in a surface of revolution SphericalPlot

Consider the surface

r[t_, n_: 2, a_: 1,b_: 1] := ((Abs@Cos[t]/a)^(2/n) + (Abs@Sin[t]/b)^(2/n))^(-n/2)
SphericalPlot3D[r[t, 2], {t, 0,  \[Pi]}, {p, 0, 2 \[Pi]}, PlotRange -> {-1, 1}, AxesLabel -> StringPart["xyz", ;;],  Mesh -> False, MaxRecursion -> 5]


There exists a vertical crease where the $$\phi=0$$ edge meets $$\phi=2\pi$$. It doesn't disappear with increased PlotPoints or MaxRecursion. How to smooth it out?

• Any reason why you don't just use ParametricPlot3D[] instead? May 6, 2020 at 5:33
• @J.M. its easier to interpret in polar/spherical coordinates..trying parametric now May 6, 2020 at 5:39
• Ah, I knew it was asked before... May 6, 2020 at 5:43
• goodness that was ~4yrs ago May 6, 2020 at 5:44

The surface normal at a vertex is computed from the polygons surrounding the vertex. This leads to a discontinuity in the normal at the boundary of the plot where the surface meets itself.

ClearAll[showVertexNormals];
showVertexNormals[g_Graphics3D, scale_ : 1,
dir_ : Directive[Thin, Black]] :=
Show[
g,
Cases[g,
GraphicsComplex[pts_, __, VertexNormals -> vn_, ___] :>
Graphics3D[{dir, Line@Transpose@{pts, pts + scale*vn}}],
Infinity]
]

r[t_, n_ : 2, a_ : 1,
b_ : 1] := ((Abs@Cos[t]/a)^(2/n) + (Abs@Sin[t]/b)^(2/n))^(-n/2)
plot = SphericalPlot3D[r[t, 2], {t, 0, \[Pi]}, {p, 0, 2 \[Pi]},
PlotRange -> {-1, 1}, AxesLabel -> StringPart["xyz", ;;],
Mesh -> False, MaxRecursion -> 5];

Show[showVertexNormals[plot, 0.15], ViewPoint -> {5, 0, 0}]


If you can formulate the correct NormalsFunction, you can fix this problem:

plot2 = SphericalPlot3D[r[t, 2], {t, 0, \[Pi]}, {p, 0, 2 \[Pi]},
PlotRange -> {-1, 1}, AxesLabel -> StringPart["xyz", ;;],
Mesh -> False, MaxRecursion -> 5,
NormalsFunction ->
Function[{x, y, z, t, p, r}, {Cos[p], Sin[p], Sign[z]}]
]

• thnx for posting.. J.M. had pointed me to your other answer Sep 28, 2021 at 16:52
• @lineage My other answer wasn't there when J.M. pointed out the question. I discovered the other question after I posted this one. Then I decided to post roughly the same answer there. I suppose someone might mark them as duplicates. Sep 28, 2021 at 17:01
• oh I see...that's some convoluted timeline ;) Sep 28, 2021 at 18:36

In light of J.M.'s comment here, using ParametricPlot3Dinstead:

r[t_, n_: 2, a_: 1,b_: 1] := ((Abs@Cos[t]/a)^(2/n) + (Abs@Sin[t]/b)^(2/n))^(-n/2)
coords = CoordinateTransform["Spherical" -> "Cartesian", {r, t, p}];
ParametricPlot3D[coords /. r -> r[t, 2], {t, 0, \[Pi]}, {p, 0, 2 \[Pi]},
MaxRecursion -> 5, Mesh -> None, PlotRange -> {-1, 1}]