Tikz 中的无底三角形节点

Tikz 中的无底三角形节点

我目前正在尝试绘制一个形状像“无底”三角形或尖括号形状的节点威格莫尔图(代表庭审辩论的图表)。在下面的例子中,我理想情况下希望删除节点 7 旁边三角形的右侧边缘(以显示攻击,而不是支持)。

威格莫尔 (Wigmore) 图表示例

我看过pgf 手册,第 75.5 节,描述了定义新的节点形状,但我发现它非常复杂。有没有更简单的方法,比如我错过的包或工作示例?

答案1

毫无疑问,创造新的形状是相当复杂的,但它们必须具有相当的多功能性。

以下内容不完整,可能没有足够的注释来真正提供帮助。不过,我从Chalamish 等人(2011)

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\makeatletter
\newif\ifpgfshapebaselesstrianglehasinline
\newif\ifpgfshapebaselesstriangleclose
\pgfkeys{/pgf/.cd,
  baseless triangle apex angle/.style={/pgf/isosceles triangle apex angle=#1},
  baseless triangle inline/.is if=pgfshapebaselesstrianglehasinline,
  baseless triangle has base/.is if=pgfshapebaselesstriangleclose
}

\pgfdeclareshape{baseless triangle}{
  % Copy some stuff from the isosecles triangle
  \inheritsavedanchors[from={isosceles triangle}]
  \inheritanchor[from={isosceles triangle}]{center}
  \inheritanchor[from={isosceles triangle}]{north}
  \inheritanchor[from={isosceles triangle}]{south}
  \inheritanchor[from={isosceles triangle}]{east}
  \inheritanchor[from={isosceles triangle}]{west}
  \inheritanchorborder[from={isosceles triangle}]
  \backgroundpath{%
    % The isoceles triangle defines lots of parameters
    % in the \trianglepoints macro.
        \trianglepoints%
        {%
            \pgftransformshift{\centerpoint}%
            \pgftransformrotate{\rotate}%
            % This bit is a bit of a kludge to ensure the inline
            % is at the top of the figure.
            \pgftransformyscale{cos(\rotate)}%
            \pgfpathmoveto{\lowerleft}%
            \pgfpathlineto{\apex}%
            \pgfpathlineto{\lowerleft\pgf@y=-\pgf@y}%
            % Close the base?
            \ifpgfshapebaselesstriangleclose%
              \pgfpathclose%
            \fi%
            % Draw the inline?
            \ifpgfshapebaselesstrianglehasinline
              \pgfpointdiff{\lowerleft}%
                 {\pgfpointlineattime{0.125}{\lowerleft}{\lowerleft\pgf@y=-\pgf@y}}%
                \pgfgetlastxy{\x}{\y}%
                \pgfmathveclen{\x}{\y}%
                \let\inlineshift=\pgfmathresult%
            % Calculate where the inline hits the sloped line of the triangle.
            \pgfmathparse{\inlineshift/2/sin(\pgfkeysvalueof{/pgf/isosceles triangle apex angle}/2)}%
            \let\inlineendshift=\pgfmathresult
            \pgfpathmoveto{\pgfpointadd{\pgfpoint{0pt}{-\inlineshift}}{\lowerleft}}%
            \pgfpathlineto{\pgfpointlineatdistance{\inlineendshift}{\apex}{\lowerleft}\pgf@y=-\pgf@y}%
        \fi%
    }
    }
}


\pgfdeclareshape{inline circle}{
  % Copy some stuff from the circle
  \inheritsavedanchors[from={circle}]
  \inheritanchor[from={circle}]{center}
  \inheritanchor[from={circle}]{north}
  \inheritanchor[from={circle}]{south}
  \inheritanchor[from={circle}]{east}
  \inheritanchor[from={circle}]{west}
  \inheritanchorborder[from={circle}]
  \backgroundpath{%
     \pgftransformshift{\centerpoint}%
     \pgfmathsetlengthmacro\radius{\radius-max(\pgfkeysvalueof{/pgf/outer xsep},\pgfkeysvalueof{/pgf/outer ysep})}%  
     \pgfpathcircle{\centerpoint}{\radius}%
     \pgfpathmoveto{\pgfpointpolar{45}{\radius}}%
     \pgfpathlineto{\pgfpointpolar{135}{\radius}}%
    }
}


\pgfdeclareshape{inline rectangle}{
  % Copy some stuff from the rectangle
  \inheritsavedanchors[from={rectangle}]
  \inheritanchor[from={rectangle}]{center}
  \inheritanchor[from={rectangle}]{north}
  \inheritanchor[from={rectangle}]{south}
  \inheritanchor[from={rectangle}]{east}
  \inheritanchor[from={rectangle}]{west}
  \inheritanchorborder[from={rectangle}]
  \backgroundpath{%
     \pgfmathsetlengthmacro\outerxsep{\pgfkeysvalueof{/pgf/outer xsep}}%
     \pgfmathsetlengthmacro\outerysep{\pgfkeysvalueof{/pgf/outer ysep}}%
     \pgfpointadd{\southwest}{\pgfpoint{\outerxsep}{\outerysep}}%
     \pgfgetlastxy\a\b
     \pgfpointadd{\northeast}{\pgfpointscale{-1}{\pgfpoint{\outerxsep}{\outerysep}}}%
     \pgfgetlastxy\c\d
     \pgfpathrectanglecorners{\pgfpoint{\a}{\b}}{\pgfpoint{\c}{\d}}%
     \pgfpathmoveto{\pgfpoint{\a}{\b+(\d-\b)*0.875}}%
     \pgfpathlineto{\pgfpoint{\c}{\b+(\d-\b)*0.875}}%
    }
}





\tikzset{
  defense explanatory/.style={
    draw,
    baseless triangle,
    baseless triangle apex angle=60,
    baseless triangle inline=true,
    baseless triangle has base=false
  },
  prosecution explanatory/.style={
    draw,
    baseless triangle,
    baseless triangle apex angle=60,
    baseless triangle inline=false,
    baseless triangle has base=false
  },
    defense corroborative/.style={
      draw,
      shape border rotate=180,
      baseless triangle,
      baseless triangle apex angle=60,
      baseless triangle inline=true,
      baseless triangle has base=true
    },
    prosecution corroborative/.style={
      draw,
      shape border rotate=180,
      baseless triangle,
      baseless triangle apex angle=60,
      baseless triangle inline=false,
      baseless triangle has base=true
    },
    defense circumstantial/.style={
      draw,
      inline circle,
      minimum size=0.5cm
    },
    prosecution circumstantial/.style={
      draw,
      circle,
      minimum size=0.5cm
    },
    defense testimonial/.style={
        draw,
        inline rectangle,
        minimum width=.375cm,
        minimum height=0.5cm
    },
    prosecution testimonial/.style={
        draw,
        rectangle,
        minimum width=.375cm,
        minimum height=0.5cm
    }
}
\begin{document}


\begin{tabular}{llcc}
&& Defense & Prosecution \\\\
1. & Testimonial & \tikz\node[defense testimonial] {}; & \tikz\node[prosecution testimonial] {}; \\
2. & Circumstantial & \tikz\node[defense circumstantial] {}; & \tikz\node[prosecution circumstantial] {}; \\
3. & Explanatory & \tikz\node [defense explanatory]  {}; &  \tikz\node[prosecution explanatory] {}; \\
4. & Corroborative & \tikz\node [defense corroborative]  {}; &  \tikz\node[prosecution corroborative] {}; \\
\end{tabular}


\end{document}

在此处输入图片描述

或者,如果我们小心outer sep(即,它很小或0pt),则可以在绘制节点后向节点添加“注释”,因此不需要新的形状:

\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,shapes.geometric}
\tikzset{node annotation/.style={%
 alias=last node,% Ensure node has name
 append after command={%
      \pgfextra{\pgfinterruptpath\pgfscope#1\endpgfscope\endpgfinterruptpath}
}}}


\tikzset{%
  defense explanatory/.style={
     isosceles triangle, 
     isosceles triangle apex angle=60,
     draw=none,
     node annotation={%
       \draw (last node.left corner) -- (last node.apex)
         -- (last node.right corner);
       \draw let \p1=(last node.apex), \p2=(last node.right corner),
         \n1={veclen(\x2-\x1,\y2-\y1)} in ($(\p1)!0.125!(\p2)$) 
         -- ++ (150:\n1*sin 60);
     }
    },
    prosecution explanatory/.style={
        isosceles triangle, 
        isosceles triangle apex angle=60,
        draw=none,
        node annotation={% Don't really need this
          \draw (last node.left corner) -- (last node.apex)
            -- (last node.right corner) -- cycle;
        }
    },
    defense corroborative/.style={
        isosceles triangle, 
        isosceles triangle apex angle=60,
        draw=none,
        node annotation={%
         \draw (last node.left corner) -- (last node.apex)
           -- (last node.right corner) -- cycle;
         \draw let \p1=(last node.apex), \p2=(last node.right corner),
           \n1={veclen(\x2-\x1,\y2-\y1)} in ($(\p1)!0.125!(\p2)$) 
           -- ++ (150:\n1*cos 30);
        }
    },
    prosecution corroborative/.style={
        isosceles triangle, 
        isosceles triangle apex angle=60,
        draw=none,
        node annotation={% Don't really need this
        \draw (last node.left corner) -- (last node.apex)
            -- (last node.right corner) -- cycle;
        }
    },
    defense circumstantial/.style={
        circle,
        minimum size=.5cm,
        draw=none,
        node annotation={%
         \clip [preaction=draw]let \p1=(last node.east), \p2=(last node.west), \n1={\x2-\x1} in
          (last node) circle [radius=\n1/2];
       \draw (last node.45) -- (last node.135);
        }
    },
    prosecution circumstantial/.style={
      minimum size=.5cm,
        circle,
        draw,
    },
    defense testimonial/.style={
        rectangle,
        minimum height=0.5cm,
      minimum width=0.375cm,
        draw,
        node annotation={%
            \draw let \p1=($(last node.north west)!0.125!(last node.south west)$),
              \p2=($(last node.north east)!0.125!(last node.south east)$) in
               (\p1) -- (\p2);
        }
    },
    prosecution testimonial/.style={
      minimum height=0.5cm,
      minimum width=0.375cm,
        rectangle,
        draw,
    }
}

\begin{document}



\begin{tabular}{llcc}
&& Defense & Prosecution \\\\
1. & Testimonial & \tikz\node[defense testimonial] {}; & \tikz\node[prosecution testimonial] {}; \\
2. & Circumstantial & \tikz\node[defense circumstantial] {}; & \tikz\node[prosecution circumstantial] {}; \\
3. & Explanatory & \tikz\node [defense explanatory]  {}; &  \tikz\node[prosecution explanatory] {}; \\
4. & Corroborative & \tikz\node [defense corroborative]  {}; &  \tikz\node[prosecution corroborative] {}; \\
\end{tabular}


\end{document}

结果将(大致)与以前相同。

相关内容