\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usepackage{pgfplots}
\usepgfplotslibrary{patchplots}
\pgfplotsset{compat=1.8}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shadings}
\usepackage{xcolor}
\definecolor{lgray}{RGB}{220,220,220}
\definecolor{mygray}{RGB}{180,180,180}
\begin{document}
\begin{tikzpicture}[scale=2]
\begin{axis}[axis equal image, axis lines=center, ticks=none, view/h=110, view/v=20]
%sphere
\addplot3[surf, shader=flat, faceted color=lgray, lgray, z buffer = sort, samples = 35,
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)});
\addplot3+[domain=0:2*pi, samples=50, samples y=0, no marks, smooth, thick, black]({0},{2*sin(deg(x))},{2*cos(deg(x))});
%viviani cylinder parts
\addplot3[surf, shader=flat, opacity = 0.5, color=mygray, faceted color=mygray, 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=flat, opacity = 0.5, color=mygray, faceted color=mygray, 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:4*pi, samples=50, samples y=0, no marks, smooth, dotted, black]({2*cos(deg(x))},{2*sin(deg(x))},{0});
%equator cylinder
\addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, thick,black]({1-cos(deg(x))},{sin(deg(x))},{0});
\end{axis}
\end{tikzpicture}
\end{document}
上述代码生成以下输出:
我不需要网格。但是根据这里的类似答案,不可能同时没有网格和半透明表面。
第二个问题:如何修复圆柱交叉点周围的小圆圈?它具有与其他曲线完全相同的设置,但会分成几段。
答案1
将光滑表面的不透明度设置为非平凡值没有任何问题。请注意,我稍微改变了参数化。
\documentclass{article}
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{pgfplots}
\pgfplotsset{compat=1.16}
\definecolor{lgray}{RGB}{220,220,220}
\definecolor{mygray}{RGB}{180,180,180}
\begin{document}
\begin{tikzpicture}[]
\begin{axis}[scale=2,axis equal image, axis lines=center, ticks=none, view/h=110, view/v=20]
%sphere
\addplot3[surf, shader=flat, faceted color=lgray, lgray, z buffer = sort, samples = 35,
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)});
\addplot3+[domain=0:2*pi, samples=50, samples y=0, no marks, smooth, thick, black]({0},{2*sin(deg(x))},{2*cos(deg(x))});
%equator
\addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, dotted, black]({2*cos(deg(x))},{2*sin(deg(x))},{0});
%viviani cylinder parts
\addplot3[surf, shader=interp, opacity = 0.5, %color=mygray, faceted color=mygray, z buffer = sort,
samples = 35,colormap/blackwhite,point meta=+0.3*y,
variable = \u, variable y = \v, domain = 0:360, y domain = -2:0, ]
({1+cos(u)}, {sin(u)}, {max(-sqrt(2*abs(2-1-cos(u))),\v)});
\addplot3[surf, shader=interp, opacity = 0.5, %color=mygray, faceted color=mygray, z buffer = sort,
samples = 35,colormap/blackwhite,point meta=+0.3*y,
variable = \u, variable y = \v, domain = 0:360, y domain = 0:2, ]
({1+cos(u)}, {sin(u)}, {min(sqrt(2*abs(2-1-cos(u))),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 cylinder
\addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, thick,black]({1-cos(deg(x))},{sin(deg(x))},{0});
\end{axis}
\end{tikzpicture}
\end{document}