# How can I mend this broken heart?

Try to evaluate the following code:

ContourPlot3D[(x^2 + 9/4 y^2 + z^2 - 1)^3 == x^2 z^3 + 9/80 y^2 z^3,
{x, -6/5, 6/5}, {y, -6/5, 6/5}, {z, -6/5, 3/2},
Mesh -> None, Boxed -> False, AxesLabel -> {"x", "y", "z"},
PlotPoints -> 50, Axes -> False,
ContourStyle -> Directive[Red, Opacity[0.58], Specularity[Yellow, 30]],
AspectRatio -> 1.15, ViewPoint ->{-0.930, -3.137, -0.860}]


The resulted heart looks broken:

Increase the PlotPoints value to up to 200 improves the appearance but does not solve it.

What is happening?

-
You have to orbit the picture to reproduce the problem – WolframFan Jul 26 '14 at 5:38
Does that mean you cannot reproduce the problem? which version you are using? – LCFactorization Jul 26 '14 at 5:42
I can reproduce it with PlotPoints less than 250, I am using v9 at the moment. When I first ran the command I had to rotate/orbit the picture to the same angle as your screenshot to see the problem (artifacts along the x axis). – WolframFan Jul 26 '14 at 5:45
It appears that this is a problem only when z=0. try to plot ((x^2 + 9/4 y^2 + z^2 - 1)^3 == (x^2 z^3 + 9/80 y^2 z^3)) /. z -> 0 using ContourPlot to see what I mean – Algohi Jul 26 '14 at 5:58
so its not a bug then? – chris Jul 26 '14 at 19:02

Taking the cube root on both sides fixes the problem, and then you don't need lots of PlotPoints any more.

ContourPlot3D[(x^2 + 9/4 y^2 + z^2 - 1) == CubeRoot[x^2 z^3 + 9/80 y^2 z^3],
{x, -6/5, 6/5}, {y, -6/5, 6/5}, {z, -6/5, 3/2}, Mesh -> None, Boxed -> False,
AxesLabel -> {"x", "y", "z"}, Axes -> False,
ContourStyle -> Directive[Red, Opacity[0.58], Specularity[Yellow, 30]],
AspectRatio -> 1.15, ViewPoint -> {-0.930, -3.137, -0.860}]


As Algohi pointed out, the problem only occurs at $z = 0$, at which the original equation becomes

(x^2 + 9/4 y^2 + z^2 - 1)^3 == x^2 z^3 + 9/80 y^2 z^3 /. z -> 0

(-1 + x^2 + (9 y^2)/4)^3 == 0


Here every zero crossing is a critical point: the function doesn't cross zero briskly like most functions do, it lingers in the neighbourhood because its derivative is zero as well. Since the ContourPlot functions find the zero crossings numerically, they have a hard time getting the location exactly right. Take your favourite ContourPlot of any function $f(x,y)=0$ and try plotting $f(x,y)^3=0$ instead, and you'll see what happens. (Though if you plot $f(x,y)^2=0$ you might not see anything at all.)

-
(+1) To make it work in version 8, I defined CubeRoot[x_] := (Abs[x]^(1/3) Sign[x]). – Jens Jul 26 '14 at 17:22
@RahulNarain +1, not only resolution of problem but explanation...very nice – ubpdqn Jul 26 '14 at 23:32