# Plot3D fails to display a discontinuous function

w = 100 π;
vra1[t_] := 0.8 Sin[w t];
vrb1[t_] := 0.8 Sin[w t - 2 π/3];
vrc1[t_] := 0.8 Sin[w t + 2 π/3];
ia[t_, θ_] := 7.2 Sin[w t - θ];
ib[t_, θ_] := 7.2 Sin[w t - θ - 2 π/3];
ic[t_, θ_] := 7.2 Sin[w t - θ + 2 π/3];
v0[t_, θ_] :=
Sign[vra1[t]] ia[t, θ] + Sign[vrb1[t]] ib[t, θ] + Sign[vrc1[t]] ic[t, θ];
Plot3D[v0[t, θ], {t, 0, 0.02}, {θ, -π, π}]


Plot3D does not dispaly the surface v0[t, θ]; it only shows the three dimensional axes. Please help me.

• Works for me. – J. M. is away Apr 21 '13 at 3:46
• Welcome to Mma.SE! Would you please change your name for better identification? – mmjang Apr 21 '13 at 3:48
• @J.M. We suppose it's a version-related problem. It failed in version 9.0.1 as I tested. – mmjang Apr 21 '13 at 3:57
• Same here, but the function is ok because when I use the ListPlot3D I got the plot. Perhaps more PlotPoints ? – Spawn1701D Apr 21 '13 at 3:58
• @mm.Jang, what happens if you directly feed the right-hand side of v0[t, θ] to Plot3D[]? – J. M. is away Apr 21 '13 at 4:05

As far as I can tell this is a problem with the exclusions detection, which is removing all the vertices from the mesh.

A workaround is to use Exclusions -> None:

Plot3D[v0[t, θ], {t, 0, 0.02}, {θ, -π, π}, Exclusions -> None]


The problem is connected to the scale of the two input axes/domains, namely {t, 0, 0.02} and {θ, -π, π}, which have a ratio of less than 1/300. The discontinuities are at lines of the form t == const, which are, of course, perpendicular to the t axis. It is as if the excluded region is depends on the distance Sqrt[Δt^2 + Δθ^2] in the absolute geometry and not the display geometry. If the ratio of the scales is far from 1, the exclusions are not computed very accurately. Depending on whether the ratio is much less than 1 or much greater, the excluded portion of the plot is, inversely, greater or less resp. There is more to it than that, since MaxRecursion affects the computation of exclusions in an odd way. It is probably quite complicated.

### Solution

A rescaling of the t axis by about 100 produces a nice plot at the expense of having the wrong tick marks. The ticks can be fixed with the Ticks option, if desired, as shown below.

scale = 100;
tticks = First @ With[{plotrange = {{0, 0.02}, {-Pi, Pi}}},
Ticks /. AbsoluteOptions[
Graphics[{Line[Transpose@plotrange]}, PlotRange -> plotrange, Axes -> True],
Ticks]];
Plot3D[v0[t/scale, θ],
{t, 0, 0.02 scale}, {θ, -π, π},
Ticks -> {MapAt[scale # &, tticks, {All, 1}], Automatic, Automatic}]


### Some analysis of the problem

Increasing the scale too much causes discontinuites to be missed. Here only the central gap is found.

scale = 10^6;
Plot3D[v0[t/scale, θ], {t, 0, 0.02 scale}, {θ, -π, π}]


Scaling by 10 is too little. We can see that the dependency on MaxRecursion has no consistent pattern. MaxRecursion settings higher than 3 produce no plots.

scale = 10;
GraphicsRow @ Table[
Plot3D[v0[t/scale, θ], {t, 0, 0.02 scale}, {θ, -π, π}, MaxRecursion -> rec],
{rec, 0, 3}
]


Scaling t has a greater effect than increasing PlotPoints:

grid = Table[
Plot3D[
v0[t/scale, θ], {t, 0,  0.02 scale}, {θ, -π, π},
PlotPoints -> pp, ViewPoint -> Front],
{scale, {5, 10, 20}}, {pp, {15, 25, 50}}
];
Labeled[GraphicsGrid[grid, ImageSize -> 500], {"scale", "points"}, {Left, Bottom},
RotateLabel -> True, LabelStyle -> "Label"]


Hopefully, this is not as drastic as the proposal to compile the function. The trick is something well-known to those who know it:

v0[t_?NumericQ, θ_?NumericQ] :=
Sign[Through[{vra1, vrb1, vrc1}[t]]].Through[{ia, ib, ic}[t, θ]]


where I have also taken the liberty to compact the definition slightly. The idea is to thwart the preliminary symbolic analysis Plot3D[] seems to try on your function, where it becomes rather overzealous in excluding what it thinks should be excluded. It should produce the same plots featured in Simon's and Spawn's answers...

You have two options. Either you compile your function v0:

vv = Compile[{{t, _Real}, {θ, _Real}}, v0[t, θ]]


and plot it instead

Plot3D[vv[t,θ], {t, 0, 0.02}, {θ, -π, π}]


or define the two new functions f and v1

f[t_] := If[t > 0, If[π - Mod[Abs[t], 2 π] > 0 , 1, -1],
If[t<0, If[π - Mod[Abs[t], 2 π] > 0 , -1, 1], 0]]


or

f[t_] = Sin[t]/Abs[Sin[t]]


and

v1[t_, θ_] := f[w t] ia[t, θ] + f[w t - 2 π/3] ib[t, θ] +f[w t + 2 π/3] ic[t, θ];


and plot v1 instead

Plot3D[v1[t, θ], {t, 0, 0.02}, {θ, -π, π}]