我搜索了但找不到解决方案。 是否可以使用 Ti 绘制节点钾Z 是正方形而不是任意比例的矩形吗?
最小工作示例可以是这样的:
\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [circle,draw] (c100) {$c_{100}$};
\node at (3,0) [rectangle,draw] (v100) {$v_{100}$};
\draw (c100) -- (v100);
\end{tikzpicture}
\end{document}
圆形是完美的圆形,而矩形就是矩形:
我希望它是正方形。我没有找到任何形状正方形或者。
答案1
这出乎意料地困难。在下面的代码中,我定义了一个自定义节点形状square
,它继承自该rectangle
形状,但强制其大小为正方形。不幸的是,继承机制不允许重新定义继承的已保存锚点,所以我不得不从 TikZrectangle
定义中复制一些代码。
从好的方面来说,它在所有情况下都应该正确(为inner [xy]sep
、minimum {width,height}
和定义不同的值outer [xy]sep
)并且具有 的所有锚点rectangle shape
。
\documentclass[tikz,margin=5pt]{standalone}
\usepackage{tikz}
\makeatletter
% the contents of \squarecorner were mostly stolen from pgfmoduleshapes.code.tex
\def\squarecorner#1{
% Calculate x
%
% First, is width < minimum width?
\pgf@x=\the\wd\pgfnodeparttextbox%
\pgfmathsetlength\pgf@xc{\pgfkeysvalueof{/pgf/inner xsep}}%
\advance\pgf@x by 2\pgf@xc%
\pgfmathsetlength\pgf@xb{\pgfkeysvalueof{/pgf/minimum width}}%
\ifdim\pgf@x<\pgf@xb%
% yes, too small. Enlarge...
\pgf@x=\pgf@xb%
\fi%
% Calculate y
%
% First, is height+depth < minimum height?
\pgf@y=\ht\pgfnodeparttextbox%
\advance\pgf@y by\dp\pgfnodeparttextbox%
\pgfmathsetlength\pgf@yc{\pgfkeysvalueof{/pgf/inner ysep}}%
\advance\pgf@y by 2\pgf@yc%
\pgfmathsetlength\pgf@yb{\pgfkeysvalueof{/pgf/minimum height}}%
\ifdim\pgf@y<\pgf@yb%
% yes, too small. Enlarge...
\pgf@y=\pgf@yb%
\fi%
%
% this \ifdim is the actual part that makes the node dimensions square.
\ifdim\pgf@x<\pgf@y%
\pgf@x=\pgf@y%
\else
\pgf@y=\pgf@x%
\fi
%
% Now, calculate right border: .5\wd\pgfnodeparttextbox + .5 \pgf@x + #1outer sep
\pgf@x=#1.5\pgf@x%
\advance\pgf@x by.5\wd\pgfnodeparttextbox%
\pgfmathsetlength\pgf@xa{\pgfkeysvalueof{/pgf/outer xsep}}%
\advance\pgf@x by#1\pgf@xa%
% Now, calculate upper border: .5\ht-.5\dp + .5 \pgf@y + #1outer sep
\pgf@y=#1.5\pgf@y%
\advance\pgf@y by-.5\dp\pgfnodeparttextbox%
\advance\pgf@y by.5\ht\pgfnodeparttextbox%
\pgfmathsetlength\pgf@ya{\pgfkeysvalueof{/pgf/outer ysep}}%
\advance\pgf@y by#1\pgf@ya%
}
\makeatother
\pgfdeclareshape{square}{
\savedanchor\northeast{\squarecorner{}}
\savedanchor\southwest{\squarecorner{-}}
\foreach \x in {east,west} \foreach \y in {north,mid,base,south} {
\inheritanchor[from=rectangle]{\y\space\x}
}
\foreach \x in {east,west,north,mid,base,south,center,text} {
\inheritanchor[from=rectangle]{\x}
}
\inheritanchorborder[from=rectangle]
\inheritbackgroundpath[from=rectangle]
}
\begin{document}
\begin{tikzpicture}
\node[draw,square] {square with rectangular node text};
\end{tikzpicture}
\end{document}
答案2
使用库regular polygon
中的形状shapes.geometric
。正如 Alenanno 在评论中提到的,您可以定义自己的样式以减少冗长。
我不知道这个大小是怎么计算的,里面有很多空白。设置inner sep
为负值可以减小大小,但必须根据节点标签的长度修改该值。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}[square/.style={regular polygon,regular polygon sides=4}]
\node at (0,0) [circle,draw] (c100) {$c_{100}$};
\node at (3,0) [square,draw] (v100) {$v_{100}$};
\node at (3,-5) [square,inner sep=-1.3em,draw] {a much longer node label};
\node at (3,-5) [circle,draw] {a much longer node label};
\draw (c100) -- (v100);
\end{tikzpicture}
\end{document}
答案3
另一个解决方案,目前尚未提及。这个想法是将所需节点设置为一个圆圈,但不绘制它。然后使用fit
tikz 库绘制一个“适合”该节点的矩形。
\documentclass[tikz,border=2mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\begin{document}
\begin{tikzpicture}
\node at (0,0) [circle,draw] (c100) {$c_{100}$};
\node at (3,0) [circle] (v100) {$v_{100}$};
\node [rectangle,draw,fit=(v100),inner sep=0] {};
\draw (c100) -- (v100);
\end{tikzpicture}
\end{document}
答案4
另一种解决方案。它使用width
函数来定义节点的大小。由于使用相同的参数作为node contents
大小分隔符,因此必须在选项之前或选项内声明节点的名称和位置。
\documentclass[border=2mm]{standalone}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}%
[square/.style={%
draw,
minimum width=width("#1"),
minimum height=width("#1")+2*\pgfshapeinnerysep,
node contents={#1}}]
\node at (0,0) [circle,draw] (c100) {$c_{100}$};
\node at (3,0) (v100) [square={$v_{100}$}];
%or
% \node (v100) at (3,0)[square={$v_{100}$}];
%or
% \node at (3,0) [square={$v_{100}$}, name=v100];
%or
% \node[square={$v_{100}$}, name=v100, at={(3,0)}];
\node at (2,-3) (B) [square=a much longer node text];
\draw (c100) -- (v100);
\draw (B.south west) -- ++(45:6cm);
\end{tikzpicture}
\end{document}