TikZ - 围绕“森林”树的一些边缘

TikZ - 围绕“森林”树的一些边缘

我正在寻求一些帮助以获得比我的代码目前的更好的格式:请参见下面的丑陋图片。

  1. 我希望蓝线与“它的”平行边缘平行。
  2. 我还希望蓝线与“其”平行边缘的距离相同。

有可能吗? 是否有(半)自动解决方案可以完成所有这些操作?

在此处输入图片描述

\documentclass[12pt,a4paper]{article}

\usepackage{forest}

\useforestlibrary{linguistics}
\forestset{
    declare count   = {connections}{1},
}


\begin{document}

\begin{forest}
        for tree = {%
            sn edges,
            grow'  = 0,
            l      = 2.5cm,
            s sep  = 1.2cm,
            anchor = parent,
        },
        before typesetting nodes = {%
            where connections = 1{}{%
                if = {isodd(connections())}{%
                    edge path' = {%
                        foreach \i [
                            count    = \j from 0,
                            evaluate = \noexpand\j
                            as \noexpand\k
                            using \noexpand {
                                (\j == 0) ?
                                0pt :
                                ((isodd(\j)) ?
                                (\j*4pt) :
                                ((-\j + 1)*4pt))
                            }
                        ]
                        in {%
                            1, ..., \foresteoption{connections}
                        }{
                            (!u.parent anchor)
                            --
                            ([yshift = \noexpand\k].child anchor)
                        }
                    },
                }{%
                    edge path' = {%
                        foreach \i [
                            count    = \j,
                            evaluate = \noexpand\j
                            as \noexpand\k
                            using {
                                (isodd(\j)) ?
                                (\j*4pt) :
                                ((-\j + 1)*4pt)
                            }
                        ]
                        in {1,...,\foresteoption{connections}}
                        {
                            (!u.parent anchor)
                            --
                            ([yshift = \noexpand\k].child anchor)
                        }
                    },
                },
            },
        },
   %%%%
   [{}, name = start
        [$A$, name = nA
            [$B$]
            [$C$, name    = nC]
        ]
        [$D$,
            [$E$]    
            [$F$]
        ]
    ]
    \draw[blue,
          rounded corners,
          dashed,
          line width=0.7pt]          
    (start.90) --
    (nA.135) --
    (nA.45) --
    (nC.45) --
    (nC.315) --
    (nC.225) --
    (nA.315) --
    (nA.225) --
    (start.315) --
    (start.180) --
    (start.90);
\end{forest}

\end{document}

答案1

添加与边缘平行的东西并不是很困难,但我怀疑这是否是你真正想要的。

\documentclass[12pt,a4paper]{article}
\usepackage{forest}
\useforestlibrary{linguistics}
\forestset{
    declare count   = {connections}{1},
}

\tikzset{parallel path/.style args={#1--#2}{insert path={
       ($(#1)!\pgfkeysvalueof{/tikz/parallel distance}!90:(#2)$)
        -- ($(#2)!\pgfkeysvalueof{/tikz/parallel distance}!-90:(#1)$)
}},parallel distance/.initial=1em
}

\begin{document}

\begin{forest}
        for tree = {%
            sn edges,
            grow'  = 0,
            l      = 2.5cm,
            s sep  = 1.2cm,
            anchor = parent,
        },
        before typesetting nodes = {%
            where connections = 1{}{%
                if = {isodd(connections())}{%
                    edge path' = {%
                        foreach \i [
                            count    = \j from 0,
                            evaluate = \noexpand\j
                            as \noexpand\k
                            using \noexpand {
                                (\j == 0) ?
                                0pt :
                                ((isodd(\j)) ?
                                (\j*4pt) :
                                ((-\j + 1)*4pt))
                            }
                        ]
                        in {%
                            1, ..., \foresteoption{connections}
                        }{
                            (!u.parent anchor)
                            --
                            ([yshift = \noexpand\k].child anchor)
                        }
                    },
                }{%
                    edge path' = {%
                        foreach \i [
                            count    = \j,
                            evaluate = \noexpand\j
                            as \noexpand\k
                            using {
                                (isodd(\j)) ?
                                (\j*4pt) :
                                ((-\j + 1)*4pt)
                            }
                        ]
                        in {1,...,\foresteoption{connections}}
                        {
                            (!u.parent anchor)
                            --
                            ([yshift = \noexpand\k].child anchor)
                        }
                    },
                },
            },
        },
   %%%%
   [{}, name = start
        [$A$, name = nA
            [$B$]
            [$C$, name    = nC]
        ]
        [$D$,
            [$E$]    
            [$F$]
        ]
    ]
    \path
    [parallel path={nA.child anchor--start.parent anchor}]
    coordinate[pos=0] (p0) coordinate[pos=1] (p1)
    [parallel path={start.parent anchor--nA.child anchor}]
     coordinate[pos=0] (p2)  coordinate[pos=1] (p3)
    [parallel path={nA.parent anchor--nC.child anchor}]
     coordinate[pos=0] (p4)  coordinate[pos=1.1] (p5)
    [parallel path={nC.child anchor--nA.parent anchor}]
     coordinate[pos=-0.1] (p6)  coordinate[pos=1] (p7)
    ; 
    \draw[blue,dashed,line width=0.7pt]          
    let \p1=($(p0)-(p1)$),
    \p2=($(p4)-(p5)$),
    \n1={atan2(\y1,\x1)},
    \n2={atan2(\y2,\x2)},
    \n3={\pgfkeysvalueof{/tikz/parallel distance}} in 
    (p0) -- (p1) arc[start angle=\n1-90,end angle=\n1-270,radius=\n3] 
    -- (p3) to[out=\n1,in=\n2] (p4) -- (p5)
    arc[start angle=\n2-90,end angle=\n2-270,radius=\n3] 
    -- (p7) to[out=\n2,in=\n1] cycle;
\end{forest}
\end{document}

在此处输入图片描述

显然,问题出C在锚点的东边,而不仅仅是边缘的下方。

你的大部分代码都没有用到,如果一个人放弃,那么sn edges边缘就会很好,一个人会得到

\documentclass[12pt,a4paper]{article}
\usepackage{forest}
\tikzset{parallel path/.style args={#1--#2}{insert path={
       ($(#1)!\pgfkeysvalueof{/tikz/parallel distance}!90:(#2)$)
        -- ($(#2)!\pgfkeysvalueof{/tikz/parallel distance}!-90:(#1)$)
}},parallel distance/.initial=1em
}

\begin{document}

\begin{forest}
        for tree = {%
            grow'  = 0,
            l      = 2.5cm,
            parent anchor=east,
            s sep  = 1.2cm,
        },
   [{}, name = start,anchor=east
        [$A$, name = nA
            [$B$]
            [$C$, name    = nC]
        ]
        [$D$,
            [$E$]    
            [$F$]
        ]
    ]
    \path
    [parallel path={nA.child anchor--start.parent anchor}]
    coordinate[pos=0.2] (p0) coordinate[pos=1] (p1)
    [parallel path={start.parent anchor--nA.child anchor}]
     coordinate[pos=0] (p2)  coordinate[pos=1] (p3)
    [parallel path={nA.parent anchor--nC.child anchor}]
     coordinate[pos=0] (p4)  coordinate[pos=1.02] (p5)
    [parallel path={nC.child anchor--nA.parent anchor}]
     coordinate[pos=-0.02] (p6)  coordinate[pos=0.8] (p7)
    ; 
    \draw[blue,dashed,line width=0.7pt]          
    let \p1=($(p0)-(p1)$),
    \p2=($(p4)-(p5)$),
    \n1={atan2(\y1,\x1)},
    \n2={atan2(\y2,\x2)},
    \n3={\pgfkeysvalueof{/tikz/parallel distance}} in 
    (p0) -- (p1) arc[start angle=\n1-90,end angle=\n1-270,radius=\n3] 
    -- (p3) to[out=\n1,in=\n2] (p4) -- (p5)
    arc[start angle=\n2-90,end angle=\n2-270,radius=\n3] 
    -- (p7) to[out=\n2,in=\n1] cycle;
\end{forest}
\end{document}

在此处输入图片描述

相关内容