是否可以在不指定我们想要标签的位置的其他不可见节点的情况下标记图形的面/边?我目前正在使用的代码复制如下:
\documentclass{standalone}
\usepackage{tikz}
\NeedsTeXFormat{LaTeX2e}[1999/01/01]
\ProvidesPackage{freetikz}
\RequirePackage{tikz}
\pgfdeclarelayer{edgelayer}
\pgfdeclarelayer{nodelayer}
\pgfdeclarelayer{foreground}
\pgfdeclarelayer{background}
\pgfsetlayers{background,edgelayer,nodelayer,main,foreground,background}
\def\thickness{0.7pt}
\tikzstyle{dot}=[circle, draw=black, fill=black!25, inner sep=.4ex, line width=\thickness, node on layer=foreground]
\tikzstyle{blackdot}=[dot, fill=black!50]
\tikzstyle{blackdot}=[dot, fill=gray!40!white]
\tikzstyle{whitedot}=[dot, fill=white]
\tikzstyle{reddot}=[dot, fill=red]
\tikzstyle{greendot}=[dot, fill=green]
\makeatletter
\pgfkeys{%
/tikz/on layer/.code={
\pgfonlayer{#1}\begingroup
\aftergroup\endpgfonlayer
\aftergroup\endgroup
},
/tikz/node on layer/.code={
\gdef\node@@on@layer{%
\setbox\tikz@tempbox=\hbox\bgroup\pgfonlayer{#1}\unhbox\tikz@tempbox\endpgfonlayer\egroup}
\aftergroup\node@on@layer
},
/tikz/end node on layer/.code={
\endpgfonlayer\endgroup\endgroup
}
}
\def\node@on@layer{\aftergroup\node@@on@layer}
\makeatother
% Lengths
\newlength\morphismheight
\setlength\morphismheight{0.6cm}
\newlength\minimummorphismwidth
\setlength\minimummorphismwidth{0.6cm}
\newlength\stateheight
\setlength\stateheight{0.6cm}
\newlength\minimumstatewidth
\setlength\minimumstatewidth{0.89cm}
\newlength\connectheight
\setlength\connectheight{0.5cm}
\tikzset{width/.initial=\minimummorphismwidth}
% Keys
\newif\ifwedge\pgfkeys{/tikz/wedge/.is if=wedge}
\tikzset{wedge}
\newif\ifvflip\pgfkeys{/tikz/vflip/.is if=vflip}
\newif\ifhflip\pgfkeys{/tikz/hflip/.is if=hflip}
\newif\ifhvflip\pgfkeys{/tikz/hvflip/.is if=hvflip}
\newif\ifconnectnw\pgfkeys{/tikz/connect nw/.is if=connectnw}
\newif\ifconnectne\pgfkeys{/tikz/connect ne/.is if=connectne}
\newif\ifconnectsw\pgfkeys{/tikz/connect sw/.is if=connectsw}
\newif\ifconnectse\pgfkeys{/tikz/connect se/.is if=connectse}
\newif\ifconnectn\pgfkeys{/tikz/connect n/.is if=connectn}
\newif\ifconnects\pgfkeys{/tikz/connect s/.is if=connects}
\newif\ifconnectnwf\pgfkeys{/tikz/connect nw >/.is if=connectnwf}
\newif\ifconnectnef\pgfkeys{/tikz/connect ne >/.is if=connectnef}
\newif\ifconnectswf\pgfkeys{/tikz/connect sw >/.is if=connectswf}
\newif\ifconnectsef\pgfkeys{/tikz/connect se >/.is if=connectsef}
\newif\ifconnectnf\pgfkeys{/tikz/connect n >/.is if=connectnf}
\newif\ifconnectsf\pgfkeys{/tikz/connect s >/.is if=connectsf}
\newif\ifconnectnwr\pgfkeys{/tikz/connect nw </.is if=connectnwr}
\newif\ifconnectner\pgfkeys{/tikz/connect ne </.is if=connectner}
\newif\ifconnectswr\pgfkeys{/tikz/connect sw </.is if=connectswr}
\newif\ifconnectser\pgfkeys{/tikz/connect se </.is if=connectser}
\newif\ifconnectnr\pgfkeys{/tikz/connect n </.is if=connectnr}
\newif\ifconnectsr\pgfkeys{/tikz/connect s </.is if=connectsr}
\tikzset{keylengthnw/.initial=\connectheight}
\tikzset{keylengthn/.initial =\connectheight}
\tikzset{keylengthne/.initial=\connectheight}
\tikzset{keylengthsw/.initial=\connectheight}
\tikzset{keylengths/.initial =\connectheight}
\tikzset{keylengthse/.initial=\connectheight}
\tikzset{connect nw length/.style={connect nw=true, keylengthnw={#1}}}
\tikzset{connect n length/.style ={connect n =true, keylengthn ={#1}}}
\tikzset{connect ne length/.style={connect ne=true, keylengthne={#1}}}
\tikzset{connect sw length/.style={connect sw=true, keylengthsw={#1}}}
\tikzset{connect s length/.style ={connect s =true, keylengths ={#1}}}
\tikzset{connect se length/.style={connect se=true, keylengthse={#1}}}
\tikzset{connect nw < length/.style={connect nw <=true, keylengthnw={#1}}}
\tikzset{connect n < length/.style ={connect n <=true, keylengthn ={#1}}}
\tikzset{connect ne < length/.style={connect ne <=true, keylengthne={#1}}}
\tikzset{connect sw < length/.style={connect sw <=true, keylengthnw={#1}}}
\tikzset{connect s < length/.style ={connect s <=true, keylengths ={#1}}}
\tikzset{connect se < length/.style={connect se <=true, keylengthse={#1}}}
\tikzset{connect nw > length/.style={connect nw >=true, keylengthnw={#1}}}
\tikzset{connect n > length/.style ={connect n >=true, keylengthn ={#1}}}
\tikzset{connect ne > length/.style={connect ne >=true, keylengthne={#1}}}
\tikzset{connect sw > length/.style={connect sw >=true, keylengthsw={#1}}}
\tikzset{connect s > length/.style ={connect s >=true, keylengths ={#1}}}
\tikzset{connect se > length/.style={connect se >=true, keylengthse={#1}}}
% Shapes
\makeatletter
\pgfdeclareshape{morphism}
{
\savedanchor\centerpoint
{
\pgf@x=0pt
\pgf@y=0pt
}
\anchor{center}{\centerpoint}
\anchorborder{\centerpoint}
\saveddimen\savedlengthnw
{
\pgfkeysgetvalue{/tikz/keylengthnw}{\len}
\pgf@x=\len
}
\saveddimen\savedlengthn
{
\pgfkeysgetvalue{/tikz/keylengthn}{\len}
\pgf@x=\len
}
\saveddimen\savedlengthne
{
\pgfkeysgetvalue{/tikz/keylengthne}{\len}
\pgf@x=\len
}
\saveddimen\savedlengthsw
{
\pgfkeysgetvalue{/tikz/keylengthsw}{\len}
\pgf@x=\len
}
\saveddimen\savedlengths
{
\pgfkeysgetvalue{/tikz/keylengths}{\len}
\pgf@x=\len
}
\saveddimen\savedlengthse
{
\pgfkeysgetvalue{/tikz/keylengthse}{\len}
\pgf@x=\len
}
\saveddimen\overallwidth
{
\pgfkeysgetvalue{/tikz/width}{\minwidth}
\pgf@x=\wd\pgfnodeparttextbox
\ifdim\pgf@x<\minwidth
\pgf@x=\minwidth
\fi
}
\savedanchor{\upperrightcorner}
{
\pgf@y=.5\ht\pgfnodeparttextbox
\advance\pgf@y by -.5\dp\pgfnodeparttextbox
\pgf@x=.5\wd\pgfnodeparttextbox
}
\anchor{north}
{
\pgf@x=0pt
\pgf@y=0.5\morphismheight
}
\anchor{north east}
{
\pgf@x=\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=0.5\morphismheight
}
\anchor{east}
{
\pgf@x=\overallwidth
\divide \pgf@x by 2
\advance \pgf@x by 5pt
\pgf@y=0pt
}
\anchor{west}
{
\pgf@x=-\overallwidth
\divide \pgf@x by 2
\advance \pgf@x by -5pt
\pgf@y=0pt
}
\anchor{north west}
{
\pgf@x=-\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=0.5\morphismheight
}
\anchor{connect nw}
{
\pgf@x=-\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=0.5\morphismheight
\advance\pgf@y by \savedlengthnw
}
\anchor{connect ne}
{
\pgf@x=\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=0.5\morphismheight
\advance\pgf@y by \savedlengthne
}
\anchor{connect sw}
{
\pgf@x=-\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=-0.5\morphismheight
\advance\pgf@y by -\savedlengthsw
}
\anchor{connect se}
{
\pgf@x=\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=-0.5\morphismheight
\advance\pgf@y by -\savedlengthse
}
\anchor{connect n}
{
\pgf@x=0pt
\pgf@y=0.5\morphismheight
\advance\pgf@y by \savedlengthn
}
\anchor{connect s}
{
\pgf@x=0pt
\pgf@y=-0.5\morphismheight
\advance\pgf@y by -\savedlengths
}
\anchor{south east}
{
\pgf@x=\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=-0.5\morphismheight
}
\anchor{south west}
{
\pgf@x=-\overallwidth
\multiply \pgf@x by 2
\divide \pgf@x by 5
\pgf@y=-0.5\morphismheight
}
\anchor{south}
{
\pgf@x=0pt
\pgf@y=-0.5\morphismheight
}
\anchor{text}
{
\upperrightcorner
\pgf@x=-\pgf@x
\pgf@y=-\pgf@y
}
\backgroundpath
{
\pgfsetstrokecolor{black}
\pgfsetlinewidth{\thickness}
\begin{scope}
\ifhflip
\pgftransformyscale{-1}
\fi
\ifvflip
\pgftransformxscale{-1}
\fi
\ifhvflip
\pgftransformxscale{-1}
\pgftransformyscale{-1}
\fi
\pgfpathmoveto{\pgfpoint
{-0.5*\overallwidth-5pt}
{0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{0.5*\overallwidth+5pt}
{0.5*\morphismheight}}
\ifwedge
\pgfpathlineto{\pgfpoint
{0.5*\overallwidth + 15pt}
{-0.5*\morphismheight}}
\else
\pgfpathlineto{\pgfpoint
{0.5*\overallwidth + 5pt}
{-0.5*\morphismheight}}
\fi
\pgfpathlineto{\pgfpoint
{-0.5*\overallwidth-5pt}
{-0.5*\morphismheight}}
\pgfpathclose
\pgfusepath{stroke}
\end{scope}
\ifconnectnw
\pgfpathmoveto{\pgfpoint
{-0.4*\overallwidth}
{0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{-0.4*\overallwidth}
{0.5*\morphismheight+\savedlengthnw}}
\pgfusepath{stroke}
\fi
\ifconnectne
\pgfpathmoveto{\pgfpoint
{0.4*\overallwidth}
{0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{0.4*\overallwidth}
{0.5*\morphismheight+\savedlengthne}}
\pgfusepath{stroke}
\fi
\ifconnectsw
\pgfpathmoveto{\pgfpoint
{-0.4*\overallwidth}
{-0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{-0.4*\overallwidth}
{-0.5*\morphismheight-\savedlengthsw}}
\pgfusepath{stroke}
\fi
\ifconnectse
\pgfpathmoveto{\pgfpoint
{0.4*\overallwidth}
{-0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{0.4*\overallwidth}
{-0.5*\morphismheight-\savedlengthse}}
\pgfusepath{stroke}
\fi
\ifconnectn
\pgfpathmoveto{\pgfpoint
{0pt}
{0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{0pt}
{0.5*\morphismheight+\savedlengthn}}
\pgfusepath{stroke}
\fi
\ifconnects
\pgfpathmoveto{\pgfpoint
{0pt}
{-0.5*\morphismheight}}
\pgfpathlineto{\pgfpoint
{0pt}
{-0.5*\morphismheight-\savedlengths}}
\pgfusepath{stroke}
\fi
\ifconnectnwf
\draw [forward arrow style] (-0.4*\overallwidth,0.5*\morphismheight)
to (-0.4*\overallwidth,0.5*\morphismheight+\savedlengthnw);
\fi
\ifconnectnef
\draw [forward arrow style] (0.4*\overallwidth,0.5*\morphismheight)
to (0.4*\overallwidth,0.5*\morphismheight+\savedlengthne);
\fi
\ifconnectswf
\draw [forward arrow style] (-0.4*\overallwidth,-0.5*\morphismheight-\savedlengthsw)
to (-0.4*\overallwidth,-0.5*\morphismheight);
\fi
\ifconnectsef
\draw [forward arrow style] (0.4*\overallwidth,-0.5*\morphismheight-\savedlengthse)
to (0.4*\overallwidth,-0.5*\morphismheight);
\fi
\ifconnectnf
\draw [forward arrow style] (0,0.5*\morphismheight)
to (0,0.5*\morphismheight+\savedlengthn);
\fi
\ifconnectsf
\draw [forward arrow style] (0,-0.5*\morphismheight-\savedlengths)
to (0,-0.5*\morphismheight);
\fi
\ifconnectnwr
\draw [reverse arrow style] (-0.4*\overallwidth,0.5*\morphismheight)
to (-0.4*\overallwidth,0.5*\morphismheight+\savedlengthnw);
\fi
\ifconnectner
\draw [reverse arrow style] (0.4*\overallwidth,0.5*\morphismheight)
to (0.4*\overallwidth,0.5*\morphismheight+\savedlengthne);
\fi
\ifconnectswr
\draw [reverse arrow style] (-0.4*\overallwidth,-0.5*\morphismheight-\savedlengthsw)
to (-0.4*\overallwidth,-0.5*\morphismheight);
\fi
\ifconnectser
\draw [reverse arrow style] (0.4*\overallwidth,-0.5*\morphismheight-\savedlengthse)
to (0.4*\overallwidth,-0.5*\morphismheight);
\fi
\ifconnectnr
\draw [reverse arrow style] (0,0.5*\morphismheight)
to (0,0.5*\morphismheight+\savedlengthn);
\fi
\ifconnectsr
\draw [reverse arrow style] (0,-0.5*\morphismheight-\savedlengths)
to (0,-0.5*\morphismheight);
\fi
}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\node [whitedot] (d0) at (4, 8) {$\alpha$};
\node [whitedot] (d1) at (2, 4) {$\beta$};
\node [whitedot] (d2) at (6, 4) {$\gamma$};
\draw (0,.01) to[out=0, in=180] (8,.01);
\draw (d0.center) to[out=180, in=-90] (0,12);
\draw (d0.center) to[out=0, in=-90] (8, 12);
\draw (d0.center) to[out=-90, in=0] (d1.center);
\draw (d0.center) to[out=-90, in=180] (d2.center);
\draw (d1.center) to[out=180, in=90] (0, 0);
\draw (d1.center) to[out=0, in=90] (4,0);
\draw (d2.center) to[out=180, in=90] (4, 0);
\draw (d2.center) to[out=0, in=90] (8, 0);
\end{tikzpicture}
\end{document}
输出结果如下:
我希望能够用大写字母 AF 标记负空间,用小写字母 fm 标记边缘:
我可以想象只需创建 14 个额外的节点并根据需要标记它们,但我希望有一个现有的功能或可以轻松添加的功能来标记图表的“空白空间”和“边缘”,因为我将不得不制作许多像这样的图表(但平均而言更复杂)。任何帮助都值得感激。
答案1
这里有一个稍微简化的方法。让我们来看看。
包裹有意吗?
如果你不这样做,你不需要所有这些:
\documentclass{standalone}
\usepackage{tikz}
\NeedsTeXFormat{LaTeX2e}[1999/01/01]
\ProvidesPackage{freetikz}
\RequirePackage{tikz}
如果你这样做,你的代码应该有点不同,我不会在这里详细说明。
图层
... 这里其实不需要。通过改变路径的顺序,可以轻松解决未填充节点的问题。为此,首先定义一些坐标很有用。
所以流程是这样的:
- 定义
\coordinate
\draw
边界和路径相关标签并记住\coordinate
一些- “放上框架”
- 贴标签
- 标记区域
- 定义并使用样式(重构)
坐标
为了稍后能够将节点放置在这些位置,只需执行以下操作:
% ~~~ coordinates ~~~~~~~~~~~~~~~~~
\coordinate (d0) at (4, 8);
\coordinate (d1) at (2, 4);
\coordinate (d2) at (6, 4);
边界
事实证明,将多个动作组合在一起很有用,同时记住,\draw
开始一条路径,;
结束一条路径,并且其间的所有其他动作都沿着这条路径放置或执行。
这里最复杂的结构是
\draw (d0.center) to[out=180, in=-90] node[posi_1]{f} (0, 12) coordinate (D);
包含:
- 绘画
\draw (d0.center) to[out=180, in=-90] (0, 12);
\node
使用某种样式预先放置node[posi_1]{f}
(请注意缺失的\
)- 在结束路径之前记住最终坐标
(0, 12) coordinate (D);
框架”
只是为了完成图片:\draw (B) -- (C) -- (D) -- (A);
但是,您最好\draw (B) -- (C) -- (D) -- (A) - cylce;
对封闭路径进行操作,并从代码的其他位置删除从底部的 (A) 到 (B) 绘制的线。
为 alpha 等放置填充节点。
现在就可以了,因为您在调用坐标时稍后才执行此操作:
% ~~~ putting labels ~~~~~~~~~~~~~~~~~~~
\node [whitedot] at (d0) {$\alpha$};
\node [whitedot] at (d1) {$\beta$};
\node [whitedot] at (d2) {$\gamma$};
标记区域
直接:
% ~~~ regions ~~~~~~~~~~~~~~~~~~~~~~~~~~
\node[reg] at (4 ,10 ) {A};
\node[reg] at (1.5, 7 ) {B};
\node[reg] at (6.5, 7 ) {C};
\node[reg] at (4 , 4.3) {D};
\node[reg] at (2 , 2 ) {E};
\node[reg] at (6 , 2 ) {F};
样式
您可以将它们放在开头,如下所示:
\begin{tikzpicture}[ % styles
dot/.style={circle,
draw=black, fill=black!25,
inner sep=.4ex, line width=0.7},
whitedot/.style={dot, fill=white},
%
posi_1/.style={yshift= 3mm,pos=0.3 }, % for f and g
posi_2/.style={xshift=-3mm,pos=0.35}, % for h, j and l
posi_3/.style={xshift=+3mm,pos=0.35}, % for i, k and m
reg/.style={font={\huge\bfseries}}, % for the regions
]
并且只在一个地方更改所有内容。例如,您可以通过 微调 a、b、... 沿其路径的相对位置pos=...
。
据我所知,在其他地方定义的厚度没有太大意义,因为它只影响您发布的代码中的圆圈。
顺便提一句
(d0.center)
有点多余:
- 如果是
\node
,则默认锚点位于节点中心 - 如果它是一个
\coordinate
根据其定义它没有大小,即一个anchor=north
与anchor=center
因此(d0)
等等在这里就足够了。
\documentclass[10pt,border=3mm,tikz]{standalone}
%\def\thickness{2.7pt}% not the best way to do it % useless
\begin{document}
\begin{tikzpicture}[ % styles
dot/.style={circle,
draw=black, fill=black!25,
inner sep=.4ex, line width=0.7},
whitedot/.style={dot, fill=white},
%
posi_1/.style={yshift= 3mm,pos=0.3 }, % for f and g
posi_2/.style={xshift=-3mm,pos=0.35}, % for h, j and l
posi_3/.style={xshift=+3mm,pos=0.35}, % for i, k and m
reg/.style={font={\huge\bfseries}}, % for the regions
]
% ~~~ coordinates ~~~~~~~~~~~~~~~~~
\coordinate (d0) at (4, 8);
\coordinate (d1) at (2, 4);
\coordinate (d2) at (6, 4);
% ~~~ drawing the boundaries AND path-related labels ~~~~~~
\draw (0,.01) to[out= 0, in=180] (8,.01);
\draw (d0.center) to[out=180, in=-90] node[posi_1]{f} (0, 12) coordinate (D);
\draw (d0.center) to[out= 0, in=-90] node[posi_1]{g} (8, 12) coordinate (C);
\draw (d0.center) to[out=-90, in= 0] node[posi_2]{h} (d1.center);
\draw (d0.center) to[out=-90, in=180] node[posi_3]{i} (d2.center);
\draw (d1.center) to[out=180, in= 90] node[posi_2]{j} (0, 0) coordinate (A);
\draw (d1.center) to[out= 0, in= 90] node[posi_3]{k} (4,0);
\draw (d2.center) to[out=180, in= 90] node[posi_2]{l} (4, 0);
\draw (d2.center) to[out= 0, in= 90] node[posi_3]{m} (8, 0) coordinate (B);
% ~~~ "frame" ~~~
\draw (B) -- (C) -- (D) -- (A);
% ~~~ putting labels ~~~~~~~~~~~~~~~~~~~
\node [whitedot] at (d0) {$\alpha$};
\node [whitedot] at (d1) {$\beta$};
\node [whitedot] at (d2) {$\gamma$};
% ~~~ retions ~~~~~~~~~~~~~~~~~~~~~~~~~~
\node[reg] at (4 ,10 ) {A};
\node[reg] at (1.5, 7 ) {B};
\node[reg] at (6.5, 7 ) {C};
\node[reg] at (4 , 4.3) {D};
\node[reg] at (2 , 2 ) {E};
\node[reg] at (6 , 2 ) {F};
\end{tikzpicture}
\end{document}