3D 曲面图中 interp 选项的阴影始终具有垂直移动的渐变。
有没有办法获得水平梯度?
下面的示例图,只是想象球体的右侧开始是白色,并在对跖点处过渡到黑色。
\documentclass{article}
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{tikz}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{patchplots}
\usepgfplotslibrary{colormaps}
\usetikzlibrary{arrows.meta}
\usetikzlibrary{shadings}
\usepackage{xcolor}
\usepackage{tikz-3dplot}
\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=2pt}, enlarge y limits={abs=2pt}, enlarge z limits={abs=2pt}]
\addplot3+[domain=2:3.65, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({-x},{0},{0});
\addplot3+[domain=2:2.4, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{-x},{0});
\addplot3+[domain=2:2.25, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{0},{-x});
%sphere
\addplot3[surf, shader=interp, colormap={custom}{rgb255=(0,0,0)rgb255=(250,250,250)}, 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 window underlay edge
\addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%viviani cylinder parts
\addplot3[surf, shader=interp, colormap={custom}{rgb255=(100,100,100)rgb255=(255,255,255)}, z buffer = sort, samples = 35,
variable = \u, variable y = \v, domain = 0:360, y domain = -2:0, ] ({1+cos(u)}, {sin(u)}, {min(-sqrt(4 - 2*x),v)});
\addplot3[surf, shader=interp, colormap={custom}{rgb255=(255,255,255)rgb255=(100,100,100)}, z buffer = sort, samples = 35,
variable = \u, variable y = \v, domain = 0:360, y domain = 0:2, ] ({1+cos(u)}, {sin(u)}, {max(sqrt(4 - 2*x),v)});
%viviani window overlay edge
\addplot3+[domain=-pi/3:2*pi/3, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
\addplot3+[domain=5*pi/3:8*pi/3, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
\addplot3+[domain=2.34375:4.5325, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%axis extensions
\addplot3+[domain=2:3.625, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({x},{0},{0});
\addplot3+[domain=2:2.4, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{x},{0});
\addplot3+[domain=2:2.25, samples=5, samples y=0, line width= 0.37pt, no marks, smooth, solid, black]({0},{0},{x});
\end{axis}\end{tikzpicture}
\end{document}
答案1
您可以调整point meta
。我引入了一个\myangle
确定方向的角度。
\documentclass{article}
\usepackage[a4paper,top=3cm,bottom=3cm,left=3cm,right=3cm,marginparwidth=1.75cm]{geometry}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\usepgfplotslibrary{colormaps}
\begin{document}
\begin{tikzpicture}[scale=2]
\pgfmathsetmacro{\myangle}{30}
\begin{axis}[axis equal image, axis lines=center, ticks=none, view/h=120, view/v=20, enlarge x limits={abs=2pt}, enlarge y limits={abs=2pt}, enlarge z limits={abs=2pt}]
\addplot3+[domain=2:3.65, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({-x},{0},{0});
\addplot3+[domain=2:2.4, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{-x},{0});
\addplot3+[domain=2:2.25, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{0},{-x});
%sphere
\addplot3[surf, shader=interp, colormap={custom}{rgb255=(0,0,0)rgb255=(250,250,250)}, 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 window underlay edge
\addplot3+[domain=0:4*pi, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%viviani cylinder parts
\addplot3[surf, shader=interp,point meta={cos(\myangle)*x+sin(\myangle)*y},
colormap={custom}{rgb255=(255,255,255)rgb255=(100,100,100)}, z buffer = sort, samples = 35,
variable = \u, variable y = \v, domain = 0:360, y domain = -2:0, ] ({1+cos(u)}, {sin(u)}, {min(-sqrt(4 - 2*x),v)});
\addplot3[surf, shader=interp,point meta={cos(\myangle)*x+sin(\myangle)*y},
colormap={custom}{rgb255=(255,255,255)rgb255=(100,100,100)}, z buffer = sort, samples = 35,
variable = \u, variable y = \v, domain = 0:360, y domain = 0:2, ] ({1+cos(u)}, {sin(u)}, {max(sqrt(4 - 2*x),v)});
%viviani window overlay edge
\addplot3+[domain=-pi/3:2*pi/3, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
\addplot3+[domain=5*pi/3:8*pi/3, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
\addplot3+[domain=2.34375:4.5325, samples=50, samples y=0, no marks, smooth, solid, black, thin]({1+cos(deg(x))},{sin(deg(x))},{2*sin(deg(x)/2)});
%axis extensions
\addplot3+[domain=2:3.625, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({x},{0},{0});
\addplot3+[domain=2:2.4, samples=5, samples y=0, line width= 0.31pt, no marks, smooth, solid, black]({0},{x},{0});
\addplot3+[domain=2:2.25, samples=5, samples y=0, line width= 0.37pt, no marks, smooth, solid, black]({0},{0},{x});
\end{axis}\end{tikzpicture}
\end{document}
如果你将此角度设置为 110,则得到