如何使轴物理上正确地穿过球体?

如何使轴物理上正确地穿过球体?

我只见过有人希望将轴叠加在图表顶部的问题。我想做一些更高级的事情。我希望轴渲染在您希望它们位于表面内部的后面,并渲染在您希望它们位于表面外部的前面。

第一张图片是我现在拥有的。

第二张图片大致就是我想要的。(抱歉绘画编辑不佳)

\documentclass{article}
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{colormaps}
\pgfplotsset{compat=1.8}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shadings}
\usepackage{xcolor}

\begin{document}
\begin{tikzpicture}[scale=2]
\begin{axis}[axis equal image, axis lines=center, ticks=none, view/h=120, view/v=20, enlarge x limits={abs=27pt}, enlarge y limits={abs=13.3pt}, enlarge z limits={abs=10pt}]
%sphere
    \addplot3[surf, shader=interp ,colormap={custom}{rgb255=(200,200,200)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 50,
    variable = \u, variable y = \v, domain = 0:180, y domain = 0:360] ({2*cos(u)*sin(v)}, {2*sin(u)*sin(v)}, {2*cos(v)});
%viviani cylinder parts
    \addplot3[surf, shader=interp, colormap={grayslate}{rgb255=(50,50,50)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 35, 
    variable = \u, variable y = \v, domain = 0:360, y domain = -2:0, ] ({1+cos(u)}, {sin(u)}, {max(-sqrt(2*(2-x)),v)});
    \addplot3[surf, shader=interp, colormap={grayslate}{rgb255=(50,50,50)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 35, 
    variable = \u, variable y = \v, domain = 0:360, y domain = 0:2, ] ({1+cos(u)}, {sin(u)}, {min(sqrt(2*(2-x)),v)});
%viviani window edge
    \addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, thick, black]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%equator
    \addplot3+[domain=0:2*pi, samples=50, samples y=0, no marks, smooth, dotted, black, line width=0.5pt]({2*cos(deg(x))},{2*sin(deg(x))},{0});
%equator cylinder
    \addplot3+[domain=0:2*pi, samples=30, samples y=0, no marks, smooth, solid, thick, black]({1-cos(deg(x))},{sin(deg(x))},{0});
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

在此处输入图片描述

答案1

这是一种可能的方法:计算 Viviani 曲线与沿 z 轴的路径之间的交点,并使用它。

\documentclass{article}
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{colormaps,fillbetween}
\pgfplotsset{compat=1.8}

\begin{document}
\begin{tikzpicture}[scale=2]
\begin{axis}[axis equal image, axis lines=center, ticks=none, view/h=120, view/v=20, enlarge x limits={abs=27pt}, enlarge y limits={abs=13.3pt}, enlarge z limits={abs=10pt}]
%sphere
    \addplot3[surf, shader=interp ,colormap={custom}{rgb255=(200,200,200)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 50,
    variable = \u, variable y = \v, domain = 0:180, y domain = 0:360] ({2*cos(u)*sin(v)}, {2*sin(u)*sin(v)}, {2*cos(v)});
%viviani cylinder parts
    \addplot3[surf, shader=interp, colormap={grayslate}{rgb255=(50,50,50)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 35, 
    variable = \u, variable y = \v, domain = 0:360, y domain = -2:0, ] ({1+cos(u)}, {sin(u)}, {max(-sqrt(2*(2-x)),v)});
    \addplot3[surf, shader=interp, colormap={grayslate}{rgb255=(50,50,50)rgb255=(200,200,200)}, opacity=0.5, z buffer = sort, samples = 35, 
    variable = \u, variable y = \v, domain = 0:360, y domain = 0:2, ] ({1+cos(u)}, {sin(u)}, {min(sqrt(2*(2-x)),v)});
%viviani window edge
    \addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, thick,
    name path=viviani,black]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%equator
    \addplot3+[domain=0:2*pi, samples=50, samples y=0, no marks, smooth, dotted, black, line width=0.5pt]({2*cos(deg(x))},{2*sin(deg(x))},{0});
%equator cylinder
    \addplot3+[domain=0:2*pi, samples=30, samples y=0, no marks, smooth, solid, thick, black]({1-cos(deg(x))},{sin(deg(x))},{0});
    \path[name path=z-axis] (axis cs:0,0,1) -- (axis cs:0,0,2);
    \draw[name intersections={of=z-axis and viviani}] (intersection-1) --
    ++(0,9pt);
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

但请注意,如果将版本号增加到 1.16,则会出现一些问题。最有可能的是,它们来自x3d 图的使用,其中变量为uv。从长远来看,如果您将图更改为另一个参数化(例如我之前的答案中的参数化),您可能会更好。

相关内容