我正在尝试定义一种形状,用于在数据来源的图形说明中绘制代理。这些代理通常用房屋形状的符号绘制,即不规则五边形,其中底部两个角是直角,左上角和右上角相同。参见,例如https://www.w3.org/TR/2013/NOTE-prov-primer-20130430/#intuitive-overview-of-prov举例来说。我没有将图片嵌入到该页面,因为我不确定它的许可状态。
由于 tikz 中默认不存在这样的形状,因此我尝试定义自己的形状。我已成功绘制了与目标形状相似的背景路径,但无法定义锚点边框,以便 tikz 自动将指向具有该形状的节点的路径指向形状的中心。
这是我当前拥有的代码:
\documentclass{standalone}
\usepackage[utf8]{inputenc}
\usepackage{fullpage}
\usepackage{tikz}
\usetikzlibrary{math,intersections}
\tikzstyle{agent}=[draw,agentshape]
\makeatletter
\pgfdeclareshape{agentshape}{
\savedanchor{\centerpoint}{%
\pgfpoint
{\dimexpr.5\wd\pgfnodeparttextbox}%
{\dimexpr.5\ht\pgfnodeparttextbox}%
}
\anchor{center}{\centerpoint}
\savedanchor{\bottomleft}{%
\pgfpoint{-\pgfshapeinnerxsep}{-\pgfshapeinnerysep}}
\anchor{south west}{\bottomleft}
\savedanchor{\bottom}{%
\pgfpoint{.5\wd\pgfnodeparttextbox}{-\pgfshapeinnerysep}}
\anchor{south}{\bottom}
\savedanchor{\bottomright}{%
\pgfpoint{\dimexpr\wd\pgfnodeparttextbox+\pgfshapeinnerxsep}{-\pgfshapeinnerysep}}
\anchor{south east}{\bottomright}
\savedanchor{\right}{%
\pgfpoint{\dimexpr\wd\pgfnodeparttextbox+\pgfshapeinnerxsep}{\dimexpr.5\ht\pgfnodeparttextbox}}
\anchor{east}{\right}
\savedanchor{\topleft}{%
\pgfpoint{-\pgfshapeinnerxsep}{\dimexpr\ht\pgfnodeparttextbox+\pgfshapeinnerysep}}
\anchor{north west}{\topleft}
\savedanchor{\left}{%
\pgfpoint{-\pgfshapeinnerxsep}{\dimexpr.5\ht\pgfnodeparttextbox}}
\anchor{west}{\left}
\savedanchor{\topright}{%
\pgfpoint{\dimexpr\wd\pgfnodeparttextbox+\pgfshapeinnerxsep}{\dimexpr\ht\pgfnodeparttextbox+\pgfshapeinnerysep}}
\anchor{north east}{\topright}
\savedanchor{\top}{%
\pgfpoint{.5\wd\pgfnodeparttextbox}{\dimexpr1.5\ht\pgfnodeparttextbox+\pgfshapeinnerysep}}
\anchor{north}{\top}
\anchorborder{%
\@tempdima=\pgf@x%
\@tempdimb=\pgf@y%
%
\pgfmathanglebetweenpoints{\centerpoint}{\topright}%
\pgfmathsetmacro{\@toprightangle}{\pgfmathresult}%
\pgfmathanglebetweenpoints{\centerpoint}{\top}%
\pgfmathsetmacro{\@topangle}{\pgfmathresult}%
\pgfmathanglebetweenpoints{\centerpoint}{\topleft}%
\pgfmathsetmacro{\@topleftangle}{\pgfmathresult}%
\pgfmathanglebetweenpoints{\centerpoint}{\bottomleft}%
\pgfmathsetmacro{\@bottomleftangle}{\pgfmathresult}%
\pgfmathanglebetweenpoints{\centerpoint}{\bottomright}%
\pgfmathsetmacro{\@bottomrightangle}{\pgfmathresult}%
%
\pgfmathanglebetweenpoints{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}%
\pgfmathsetmacro{\@givenangle}{\pgfmathresult}%
\pgfmathparse{or(\@givenangle > \@bottomrightangle, \@givenangle <= \@toprightangle)}%
\ifnum\pgfmathresult=1%
\pgfpointintersectionoflines{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}{\bottomright}{\topright}%
\else%
\pgfmathparse{and(\@givenangle > \@toprightangle, \@givenangle <= \@topangle)}%
\ifnum\pgfmathresult=1%
\pgfpointintersectionoflines{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}{\topright}{\top}%
\else%
\pgfmathparse{and(\@givenangle > \@topangle, \@givenangle <= \@topleftangle)}%
\ifnum\pgfmathresult=1%
\pgfpointintersectionoflines{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}{\top}{\topleft}%
\else%
\pgfmathparse{and(\@givenangle > \@topleftangle, \@givenangle <= \@bottomleftangle)}%
\ifnum\pgfmathresult=1%
\pgfpointintersectionoflines{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}{\topleft}{\bottomleft}%
\else%
\pgfmathparse{and(\@givenangle > \@bottomleftangle, \@givenangle <= \@bottomrightangle)}%
\ifnum\pgfmathresult=1%
\pgfpointintersectionoflines{\centerpoint}{\pgfpoint{\@tempdima}{\@tempdimb}}{\bottomleft}{\bottomright}%
\fi
\fi
\fi
\fi%
\fi%
}
\backgroundpath{
\pgfpathmoveto{\bottomleft}
\pgfpathlineto{\bottomright}
\pgfpathlineto{\topright}
\pgfpathlineto{\top}
\pgfpathlineto{\topleft}
\pgfpathclose
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node[agent] (agent) at (1,1) {Foo};
\foreach \coord in {-2,-1.5,...,2} {
\path[draw,-] (-2,\coord) -- (agent);
\path[draw,-] (2,\coord) -- (agent);
\path[draw,-] (\coord,-2) -- (agent);
\path[draw,-] (\coord,2) -- (agent);
}
\end{tikzpicture}
\end{document}
结果如下图所示:
如您所见,从节点顶部和右侧进入的路径似乎指向文本框的左下侧,而从插图底部和左侧进入的路径指向节点下部的中心。这在顶行右侧第三条路径和右行顶部第三条路径中尤为明显。
我如何定义形状以使所有传入路径都指向节点形状的中心?
答案1
我认为一个single arrow
形状可以解决你的问题:
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{shapes.arrows}
\begin{document}
\begin{tikzpicture}[myhouse/.style={single arrow,
shape border rotate=90,
single arrow head extend=0pt,
single arrow tip angle=120}]
\node[myhouse, draw] (a) {House};
\node[myhouse, draw] at (30:2cm) (b) {House};
\draw (a)--(b);
\end{tikzpicture}
\end{document}