更智能的渐变:如何使 TikZ“阴影”遵循实际形状?

更智能的渐变:如何使 TikZ“阴影”遵循实际形状?

考虑以下 MWE:

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\shade[top color=yellow,bottom color=green] (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\end{tikzpicture}
\end{document}

其输出是

在此处输入图片描述

如您所见,top color=yellow仅影响形状的上部尖端/顶点。我期望的是以下形式

在此处输入图片描述

我为糟糕的涂装工作道歉。无论如何,我希望阴影能够遵循物体的形状:上边缘是黄色,下边缘是绿色,渐变影响整个图形,而不仅仅是上部顶点。

如何做到这一点(在 TikZ 中)?了解一般情况会很好,但如果不可能,上面的形状就足以满足我的目的。

答案1

可用的阴影只有径向或线性,但您可以使用裁剪区域来解决这个问题,并在颜色改变时多次绘制 y 坐标中某个值的偏移形状。此外,如果您将其放在范围内,您还可以使用多个裁剪形状在外面绘制其他元素。

结果:

在此处输入图片描述

梅威瑟:

\documentclass[tikz,border=20pt]{standalone}
\begin{document}
    \begin{tikzpicture}

    \begin{scope}
    \clip
    (-2,0)
        to[out=-90,in=180] (0,-2)
        to[out=0,in=-90] (2,0)
        to[out=-90-35,in=0](0,-.7)
        to[out=180,in=-55] (-2,0);

    \foreach \x [evaluate=\x as \xn using {\x*4}] in {1,...,25} {
    \fill[green!\xn!yellow,yshift=2-\x]
    (-2,0)
        to[out=-90,in=180] (0,-2)
        to[out=0,in=-90] (2,0)
        to[out=-90-35,in=0](0,-.7)
        to[out=180,in=-55] (-2,0);
    }
    \end{scope}
    \shade[top color=yellow,bottom color=red](1,0) circle (0.2);
    \end{tikzpicture}
\end{document}

答案2

欢迎来到 TeX.SE!答案是,据我所知,没有预定义的方法可以做到这一点。但是,你可以作弊并使用shadings库中附带的一些选项以及 clip 来执行你所建议的操作。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shadings}
\begin{document}
\begin{tikzpicture}
\clip (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\shade[inner color=yellow,outer color=green] (-3,0.8) arc(180:360:3);
\end{tikzpicture}
\end{document}

在此处输入图片描述

我忍不住添加一些更花哨的东西cfr 的花式径向阴影。这也是为了说明如何自定义阴影。

\documentclass[border=3.14mm,x11names,dvipsnames,svgnames]{standalone}
\usepackage{tikz}
\usetikzlibrary{shadings}
\pgfdeclareradialshading[fradialcolour1,fradialcolour2,fradialcolour3]{fncyradial}{\pgfpoint{0}{0}}{% manual 1082-1083; later - shading is assumed to be 100bp diameter ??
  color(0)=(fradialcolour1);
  color(20bp)=(fradialcolour2);
  color(40bp)=(fradialcolour3);
  color(50bp)=(fradialcolour3)
}
\tikzset{%
  fradial/.code={%
        \tikzset{%
          fancy radial/.cd,
          shading=fncyradial,
          #1
        }
  },
  fancy radial/.search also={/tikz},
  fancy radial/.cd,
  fancy radial inner colour/.code={
        \colorlet{fradialcolour1}{#1}
  },
  fancy radial mid colour/.code={
        \colorlet{fradialcolour2}{#1}
  },
  fancy radial outer colour/.code={
        \colorlet{fradialcolour3}{#1}
  },
  fancy radial inner colour=black,
  fancy radial outer colour=black,
  fancy radial mid colour=white,
  inner color/.style={
        fancy radial inner colour=#1,
  },
  outer color/.style={
        fancy radial outer colour=#1,
  },
  mid color/.style={
        fancy radial mid colour=#1,
  },
}
\begin{document}
\begin{tikzpicture}
\clip (-2,0) to[out=-90,in=180] (0,-2) to[out=0,in=-90] (2,0) to[out=-90-35,in=0] (0,-.7) to[out=180,in=-55] (-2,0);
\shade[fradial={inner color=yellow, outer color=green, mid color=yellow!70!green}] (-3,1) arc(180:360:3);
\end{tikzpicture}
\end{document}

在此处输入图片描述

当然,pgfmanual 的第 109 节中描述了所有高级选项。原则上你可以尝试使用,\pgfsetadditionalshadetransform但这需要很大的努力,而且也不会带来通用的解决方案。我还想提一下,在这里实现非线性变换似乎并不是一件容易的事(看这里)。如果不存在这个问题,人们可能能够以与bending库的工作方式类似的方式构建通用解决方案,即从路径定义非线性变换。

相关内容