2

I am trying to solve the following problem: First I would like to produce a surface plot of a function of two variables (in this particular case this surface has a saddle shape). Then I would like to draw a sphere in the same plot in such a way that the sphere is tangent to the surface at a point that can be specified freely. Achieving the first part was not a problem. For the second part, I have so far been able to place something that at least resembles a sphere somewhere in the plot (see below). However, specifying the position of where to put the sphere seems to be done not in relation to the axes that I am plotting in, but some other reference point (so (0,0) does not put the sphere at the origin of the axes).

Has someone got a suggestion for the following questions:
1) How do I make the bounding line of the ball thinner?
2) To make it look like an actual sphere, how could I add grid lines (like longitude and latitude) that are correctly projected?
3) How do I specify the position relative to the axes?

To achieve my actual goal:
4) In order to make the sphere with a given radius tangent at a user-specified point, I guess I have to calculate the position in the axes coordinate system via some external program (python ideally). How do I get that information into LateX?
5) Is there a way to do all this in python alone and get a vector graphic out that looks as great as what you get with tikz?

Sorry for the long post, but answers to at least 1-3 would be much appreciated.

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}
    \begin{tikzpicture}
        \begin{axis}
            \addplot3 [
                surf,
                shader=faceted,
                samples=25,
                domain=-4:4,
                y domain=-4:4
                ] {x^2-y^2};
            \filldraw[ball color=white] (-140,1090) circle [radius=0.25cm];
        \end{axis}
   \end{tikzpicture}
\end{document}

enter image description here

1
  • Are you aware of asymptote? And what do you mean by "position relative to the axes"?
    – user121799
    Apr 17, 2018 at 13:21

1 Answer 1

3

I'd recommend asymptote for this. All one has to do is to move to some point on the surface (with coordinates myx and myy in the code below) and then go radius units along the normal of that surface, and to draw a sphere there. (With improved(?) output.)

enter image description here

\documentclass[border=3.14pt]{standalone}
\usepackage{asypictureB}
\begin{document}
\begin{asypicture}{name=AsyPlot}
import three;
import graph3;
import grid3;
import palette;
import solids;
unitsize(1cm);
settings.outformat="pdf";
defaultrender.merge=true;
size(12cm,IgnoreAspect);
currentprojection=perspective(4,-6,4);
real f(pair z) {return 0.1*(z.x^2-z.y^2);}
// adopted from https://tex.stackexchange.com/a/212348/121799   
triple normalf(pair z) {
    static real dx=sqrtEpsilon, dy=dx;
    return (-(f((z.x+dx,z.y))-f((z.x-dx,z.y)))/2dx,
         -(f((z.x,z.y+dy))-f((z.x,z.y-dy)))/2dy,
         1);
    }   
real r1=0.5, myx=-1.0, myy=-2.0; // x-y location of the sphere and radius
triple v1=(myx,myy,f((myx,myy)))+r1*normalf((myx,myy));
triple fs(pair t){ //parametrization of a shifted sphere
  return v1+r1*(cos(t.x)*sin(t.y),sin(t.x)*sin(t.y),cos(t.y));
}
surface s1=surface(fs,(0,0),(2pi,pi),8,Spline);
surface s=surface(f,(-4,-4),(4,4),Spline);
xaxis3(XYZero(extend=true),red,Arrow3);
yaxis3(XYZero(extend=true),red,Arrow3);
zaxis3(XYZero(extend=true),red,Arrow3);
s.colors(palette(s.map(abs),Wheel()));
draw(s,render(compression=Low,merge=true));
draw(s1
  ,gray+opacity(0.25)
  ,render(merge=true), meshpen=0.6*white
);
\end{asypicture}
\end{document}

Just for fun: an animated version, almost impossible to do with pgfplots IMHO.

enter image description here

You can also use pgfplots, but ultimately you will always be limited by the fact that this has no true 3D engine. To make the line thinner, you can adjust line width. To place the sphere in the coordinate system, use axis cs:. (The problem, though, is that the radius does not get translated.) You can draw circles in the plot, the problem is to project on the visible parts. There are ways to achieve this, yet it will not be too easy to marry them to pgfplots. This has to do with the fact that there all sorts of rotated scopes are used, which interfere with the coordinate transformations made by pgfplots.

enter image description here

\documentclass{standalone}

\usepackage{amsmath}
\usepackage{pgfplots}
\pgfplotsset{compat=newest}

\begin{document}
    \begin{tikzpicture}
        \begin{axis}
            \addplot3 [
                surf,
                shader=faceted,
                samples=25,
                domain=-4:4,
                y domain=-4:4
                ] {x^2-y^2};
            \filldraw[ball color=white,line width=0.1pt] (axis
            cs:-1.40,-1.4,0.25) circle [radius=0.25cm];
            \addplot3 [line width=0.1pt,domain=70:250,samples y=0] ({-1.4+0.38*sin(x)},
            {-1.4+0.38*cos(x)},0.25);
        \end{axis}
   \end{tikzpicture}
\end{document}
7
  • Adding the equator to the sphere enhances the 3D effect a lot. Nice idea! +1
    – AlexG
    Apr 17, 2018 at 13:57
  • +1 Crazy how much effort you put into answers! Apr 17, 2018 at 15:31
  • 1
    @Dr.ManuelKuehner Thanks, but please don't confuse "nice 3D pic" with "lots of effort". ;-)
    – user121799
    Apr 17, 2018 at 16:59
  • Is the output of asymptote that you posted above a vector graphic? It does not look as clean as pgfplots, but that might be because it gets rasterised when uploading on stackexchange?
    – Quantum
    Apr 17, 2018 at 18:21
  • @Quantum I don't think that asymptote supports vector graphics for 3D output at this point (but I may be wrong). But the output is my fault, if you use size(600); instead of size(400,0);, the picture will look much better. (I didn't pay attention to this.)
    – user121799
    Apr 17, 2018 at 18:26

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .