tikz/pgfplots - 用球体绘制 3D 表面

tikz/pgfplots - 用球体绘制 3D 表面

我正在尝试解决以下问题:首先,我想生成一个二元函数的曲面图(在此特定情况下,此曲面呈马鞍形)。然后,我想在同一图中绘制一个球体,使球体与曲面相切于一个可以自由指定的点。实现第一部分不成问题。对于第二部分,到目前为止,我已经能够在图中的某个地方放置至少类似于球体的东西(见下文)。但是,指定放置球体的位置似乎不是相对于我绘制的轴,而是相对于其他参考点(因此 (0,0) 不会将球体置于轴的原点)。

有人对以下问题有什么建议吗:
1) 如何使球的边界线变细?
2) 为了使它看起来像一个真正的球体,我该如何添加正确投影的网格线(如经度和纬度)?
3) 如何指定相对于轴的位置?

为了实现我的实际目标:
4) 为了使具有给定半径的球体在用户指定的点处相切,我想我必须通过一些外部程序(最好是 python)计算轴坐标系中的位置。我如何将这些信息输入 LateX?
5) 有没有办法只用 python 完成所有这些操作,并得到一个看起来和用 tikz 得到的一样棒的矢量图形?

抱歉,帖子太长了,但如果能至少回答 1-3 个问题我将非常感激。

\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}

在此处输入图片描述

答案1

我建议使用渐近线。所要做的就是移动到表面上的某个点(使用下面的代码中的坐标myx和坐标),然后沿着该表面的法线移动单位,并在那里绘制一个球体。(输出得到改进(?))。myyradius

在此处输入图片描述

\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}

只是为了好玩:动画版本,在我看来几乎不可能用 pgfplots 来实现。

在此处输入图片描述

您也可以使用 pgfplots,但最终您将始终受到没有真正 3D 引擎这一事实的限制。要使线条更细,您可以调整line width。要将球体放置在坐标系中,请使用axis cs:。(但问题是半径不会平移。)您可以在图中绘制圆圈,问题在于投影到可见部分。有实现这一目标的方法,但将它们与 pgfplots 结合起来并不容易。这与使用各种旋转范围有关,这会干扰 pgfplots 所做的坐标变换。

在此处输入图片描述

\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}

相关内容