# How to speed up drawing a tangent plane?

I have this code to produce an interactive visualization of a tangent plane to a function:

Clear[f]
f[x_, y_] := x^3 + 2*y^3
Manipulate[
Show[
Plot3D[f[x, y], {x, -1, 1}, {y, -1, 1}, PlotStyle -> Opacity[0.8]],
Plot3D[f[point[], point[]] +
Limit[(f[point[] + h, point[]] - f[point[], point[]])/
h, h -> 0]*(x - point[]) +
Limit[(f[point[], point[] + h] - f[point[], point[]])/
h, h -> 0]*(y - point[]), {x, -1, 1}, {y, -1, 1},
PlotStyle -> Opacity[0.8], MeshStyle -> Gray]],
{{point, {0, 0}}, {-1, -1}, {1, 1}},
SaveDefinitions -> True]


It is, however, extremely slow. I suspect that the reason is that I unnecessarily compute the partial derivatives over and over again inside the second Plot3D, so my question is: how to change it?

Note: I am using the above code also for other functions as discussed here, and that is the reason for the Limit in computation of partial derivatives.

Simply move the derivative computation outside the scope of the Manipulate, using either D or Limit.

f[x_, y_] = x^3 + 2 y^3;
fx[x_, y_] = D[f[x, y], x];
fx[x_, y_] = Limit[(f[x + h, y] - f[x, y])/h, h -> 0];
fy[x_, y_] = D[f[x, y], y];
fy[x_, y_] = Limit[(f[x, y + h] - f[x, y])/h, h -> 0]
Manipulate[
x0 = p[]; y0 = p[];
Show[{
Plot3D[{f[x, y],
f[x0, y0] + fx[x0, y0] (x - x0) + fy[x0, y0] (y - y0)},
{x, -2, 2}, {y, -2, 2}, BoxRatios -> {1, 1, 1},
PlotRange -> {{-2, 2}, {-2, 2}, {-25, 25}},
PlotStyle -> {Directive[Opacity[0.6]],
Directive[Orange, Opacity[0.6]]},
ViewPoint -> {2.5, -2, 1}, ClippingStyle -> None],
Graphics3D[{PointSize[Large],
Point[{p[], p[], f[p[], p[]]}]}]
}],
{{p, {1, 1}}, {-1, -1}, {2, 2}}]

• Interesting. Why do you provide two rules for fx[x_,y_]? Sep 29 '12 at 19:36
• @mbork Either definition works, although the second clearly overwrites the first. I was simply trying to emphasize the fact that you can use either the built in D operator or the Limit definition, as you indicated that you might need to. Sep 29 '12 at 19:40
• OK, thanks. For the moment I thought that somehow the Limit one is chosen if the D doesn't work (e.g., when the function is given by a separate rule for one point). And thanks for the nicety - the large point! (I did it using a one-element list in ListPointPlot3D, definitely less elegant.) Sep 29 '12 at 19:42
• @mbork you could also show the Points using Epilog Sep 30 '12 at 2:07
• @Simon Epilog is really for 2D graphics. From the documentation: "In three-dimensional graphics, two-dimensional graphics primitives can be specified by the Epilog option. The graphics primitives are rendered in a 0,1 coordinate system." - Hence, the Show[{Plot3D[__], Graphics3D[__]}] construct. Sep 30 '12 at 2:38

The limits can be calculated analytically one time and then used inside your Manipulate. You can use With to place the final expression where you need them:

f[x_, y_] := x^3 + 2*y^3;
With[{l1 = Limit[(f[px + h, py] - f[px, py])/h, h -> 0],
l2 = Limit[(f[px, py + h] - f[px, py])/h, h -> 0]},
Manipulate[
{px, py} = point;
Show[Plot3D[f[x, y], {x, -1, 1}, {y, -1, 1},
PlotStyle -> Opacity[0.8]],
Plot3D[f[point[], point[]] + l1*(x - point[]) +
l2*(y - point[]), {x, -1, 1}, {y, -1, 1},
PlotStyle -> Opacity[0.8],
MeshStyle -> Gray]], {{point, {0, 0}}, {-1, -1}, {1, 1}},
SaveDefinitions -> True]
]

• Thanks! I just discovered With myself, too, but I've put it inside Show; I guess this doesn't make much difference. Sep 29 '12 at 19:36