为重叠的物体绘制适当的阴影

为重叠的物体绘制适当的阴影

我绘制了由多个重叠节点组成的图像。如果我drop shadow向每个节点添加一个,则第二个节点的阴影将绘制在第一个节点上,如下图所示(cylinder由从下到上绘制的两个节点组成,每个节点都有一个阴影):

例子

(感谢 zeroth 提供图片来回复此帖相关问题。 )

TikZ 的文档明确指出:您只能将阴影应用于路径,而不能应用于范围。我使用的解决方法是:

  • 创建一个\foreach循环,循环遍历{drop shadow,},从而首先分配drop shadow,然后将空字符串分配给宏,例如,\s
  • 用于\s每个节点的选项。(也许我可以附加\severy nodeevery path,但还没有尝试。)

当然,在生成的 PDF 中,图像被绘制了两次,这在一定程度上影响了渲染速度,甚至可能影响了生成的 PDF 的大小。此外,生成的代码相当丑陋。我的问题是:

  1. 有没有一种干净的方法可以使用 TikZ/pgf 功能实现所需的结果?也许可以将一系列 TikZ/pgf 命令转换为单个路径?
  2. 如果不:
    • 是否可以在第一遍中给节点和路径添加一些样式参数,以便在绘制阴影时不渲染图像的细节?
    • shadowgroup从技术上来说,实现一个可以隐藏其背后的复杂性和丑陋的环境是否可行?

答案1

后续问题将选项传递给预操作内部创建的范围令我惊讶的是,这个问题可以用我的代码来解决TikZ 中的“Z 级别”我将不得不求助于惊讶(和抄袭)现在因为事实证明这drop shadow不需要任何修改就可以工作(我的解决方案往往是黑客行为的缩影,所以一个人可以为没有经过测试的东西工作这一事实绝对是不寻常的)。

这是代码。我擅自删除了嵌套的 tikzpictures(请参阅在 tikzpicture 的开头设置的最重要的变量是什么?范围是什么?以及其中的链接)。

\documentclass{article}
%\url{https://tex.stackexchange.com/q/43618/86}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shadows}

\pgfdeclarelayer{back}
\pgfsetlayers{back,main}

\makeatletter
\pgfkeys{%
  /tikz/on layer/.code={
    \pgfonlayer{#1}\begingroup
    \aftergroup\endpgfonlayer
    \aftergroup\endgroup
  },
  /tikz/node on layer/.code={
    \pgfonlayer{#1}\begingroup
    \expandafter\def\expandafter\tikz@node@finish\expandafter{\expandafter\endgroup\expandafter\endpgfonlayer\tikz@node@finish}%
  },
}
\makeatother

\newcommand{\dbpart}[1]{
    \node[drop shadow={opacity=1.0,on layer=back},draw, cylinder, shape aspect=1.5, inner sep=0.3333em, fill=white,
    rotate=90, minimum width=1cm, minimum height=0.45cm] (cyl) at (0,#1) {};
}
\newcommand{\dbicon}[1][]{
  \begin{scope}[#1]
      \dbpart{0cm}%
      \dbpart{0.4cm}%
  \end{scope}
}

\begin{document}
\begin{tikzpicture}
      \dbicon
\end{tikzpicture}
\end{document}

事情是这样的(哦,我fill=white同意 Frédéric 的观点,它看起来更漂亮)。

在背景图层上放置阴影

让我们先不填充,只是为了看看。

背景层上有阴影,主要形状未填充

答案2

这个答案可以完成任务,但可能不如您希望的那样干净和高效。它建立在您上一个问题的答案之上,并添加了层(背景层)。

\documentclass[border=5pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{backgrounds}
\usetikzlibrary{shapes.geometric}
\usetikzlibrary{shadows}

\newcommand{\dbpart}[1]{
    \node[draw, cylinder, shape aspect=1.5, inner sep=0.3333em, 
    rotate=90, minimum width=1cm, minimum height=0.45cm] (cyl) at (0,#1) {};
    \begin{scope}[on background layer]
    \node[drop shadow={gray!50,opacity=1},cylinder, shape aspect=1.5, inner sep=0.3333em, 
    rotate=90, minimum width=1cm, minimum height=0.45cm] (cyl) at (0,#1) {};
    \end{scope}
}
\newcommand{\dbicon}{
    \begin{tikzpicture}
      \dbpart{0cm}%
      \dbpart{0.4cm}%
    \end{tikzpicture}
}

\begin{document}
\begin{tikzpicture}
  \node[inner sep=0pt] {
      \dbicon
  };
\end{tikzpicture}

\end{document}

结果是

结果平局

就我个人而言,如果我要使用阴影,我也会填充圆柱体(fill=white)。结果将是

填充结果

答案3

这里有一个形状声明作为起点。我没有完全解决阴影问题,实际上我不明白为什么它看起来乱码,但我希望稍后完成它。如果有人能看看我将不胜感激。

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shadows,shapes.geometric}

\makeatletter
\pgfdeclareshape{dbicon}
{
    \anchor{center}{\pgfpointorigin}
    \savedanchor{\west}{\pgf@y = 0mm \pgf@x = 1cm} %%
    \anchor{east}{\west \pgf@x=-\pgf@x}
    \anchor{west}{\west}
    \savedanchor{\north}{\pgf@y = 3mm \pgf@x = 0mm} %%
    \anchor{north}{\north}

    \backgroundpath{
        \west \pgf@xa=\pgf@x \pgf@xb=0.75\pgf@xa
        \pgfpathmoveto{\pgfpoint{\pgf@xa}{0}}
        \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@xb}}
        \pgfpatharc{0}{-180}{\pgf@xa and 0.3\pgf@xb}
        \pgfpathlineto{\pgfpoint{-\pgf@xa}{0}}
        \pgfpathellipse{\pgfpointorigin}{\pgfpoint{\pgf@xa}{0mm}}{\pgfpoint{0mm}{0.3\pgf@xb}}
        \pgftransformshift{\pgfpoint{0}{0.9\pgf@xa}} %Shift up and make a full cylinder
        \west \pgf@xa=\pgf@x \pgf@xb=0.75\pgf@xa
        \pgfpathmoveto{\pgfpoint{\pgf@xa}{0}}
        \pgfpathlineto{\pgfpoint{\pgf@xa}{-\pgf@xb}}
        \pgfpatharc{0}{-180}{\pgf@xa and 0.3\pgf@xb}
        \pgfpathlineto{\pgfpoint{-\pgf@xa}{0}}
        \pgfpathellipse{\pgfpointorigin}{\pgfpoint{\pgf@xa}{0mm}}{\pgfpoint{0mm}{0.3\pgf@xb}}
    }
}
\makeatother

\begin{document}
\begin{tikzpicture}
\node[dbicon,shade,shading angle=90,draw,drop shadow] (a) at (0,0) {};
\end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容