从指针到节点的最短路径

从指针到节点的最短路径

有没有办法让调出指针使用最短路径到达节点?所以这在某种程度上是一个优化问题 ;-) 这是我的代码。调出部分复制自这里

    \documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usetikzlibrary{positioning,chains, shapes.geometric,decorations.pathreplacing,calc,shadows.blur,shapes}
\tikzset{
    add path/.style = {
        decoration={show path construction,
            moveto code={
                \xdef\savedpath{\savedpath (\tikzinputsegmentfirst)}
            },
            lineto code={
                \xdef\savedpath{\savedpath -- (\tikzinputsegmentlast)}
            },
            curveto code={
                \xdef\savedpath{\savedpath .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast)}
            },
            closepath code={
                \xdef\savedpath{\savedpath -- cycle}
            }
        },
        decorate
    },
    store path/.style = {add path},
    store path/.prefix code={\xdef\savedpath{}},
    callouts/.style={
        store path,
        append after command={
            foreach \target in {#1}{
                ($(callout)!2pt!-90:\target$)--\target --($(callout)!2pt!90:\target$)
            } \savedpath
        },
        alias=callout
    },
    custom style/.style={fill=blue!20,text=},
}
\begin{document}
\begin{tikzpicture}[
[baserect/.style={text width=0.5cm,align=left,draw,},
diam/.style={diamond,draw,align=left,text width=1cm,inner sep=1.5pt,fill=yellow,text=white,minimum size=2cm},
basecirc/.style={circle,draw,align=center,text width=1.5cm},
circ/.style={basecirc,fill=blue!60,text=black}]     
\node [diam] (1) {asdf};
\node [circ, right=5 of 1] (2) {asdf};
\node [diam, below=2 of 2] (3) {asdf};
\path[custom style] (3,1) node[callouts={(1.east),(2.west),(3.north west)}]{blah blah};
\end{tikzpicture} 
\end{document}

编辑:我的问题是如何优化从标注到指针接触节点的距离。在图像中,绿线比红线短。如何找到最靠近标注的节点点的坐标? 在此处输入图片描述

答案1

一种可能性不是真正的优化,但可以实现,那就是使用fit库。这个库创建一个包含所有坐标的节点。这个节点是bounding box包含所有坐标的最小节点。一旦完成,我们就可以例如将标注放在这个边界框的中心。

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usetikzlibrary{positioning,chains, shapes.geometric,decorations.pathreplacing,calc,shadows.blur,shapes}
\usetikzlibrary{fit}
\tikzset{
    add path/.style = {
        decoration={show path construction,
            moveto code={
                \xdef\savedpath{\savedpath (\tikzinputsegmentfirst)}
            },
            lineto code={
                \xdef\savedpath{\savedpath -- (\tikzinputsegmentlast)}
            },
            curveto code={
                \xdef\savedpath{\savedpath .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast)}
            },
            closepath code={
                \xdef\savedpath{\savedpath -- cycle}
            }
        },
        decorate
    },
    store path/.style = {add path},
    store path/.prefix code={\xdef\savedpath{}},
    callouts/.style={
        store path,
        append after command={
            foreach \target in {#1}{
                ($(callout)!2pt!-90:\target$)--\target --($(callout)!2pt!90:\target$)
            } \savedpath
        },
        alias=callout
    },
    custom style/.style={fill=blue!20,text=},
}
\begin{document}
\begin{tikzpicture}[
[baserect/.style={text width=0.5cm,align=left,draw,},
diam/.style={diamond,draw,align=left,text width=1cm,inner sep=1.5pt,fill=yellow,text=white,minimum size=2cm},
basecirc/.style={circle,draw,align=center,text width=1.5cm},
circ/.style={basecirc,fill=blue!60,text=black}]     
\node [diam] (1) {asdf};
\node [circ, right=5 of 1] (2) {asdf};
\node [diam, below=2 of 2] (3) {asdf};
\node[draw=red, fit=(1) (2) (3)](fit) {box};
\path[custom style] (fit) node[callouts={(1.east),(2.west),(3.north west)}]{blah blah};
\end{tikzpicture} 
\end{document}

输出:

节点调出

答案2

这只是 AndréC 醒来前的临时帖子。您可以利用已经加载库的事实相当轻松地做到这一点calc,但此代码重新定义了语法,即您不能再将指针放在括号中。

\documentclass[border=10mm]{standalone}
\usepackage{tikz}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usetikzlibrary{positioning,chains, shapes.geometric,decorations.pathreplacing,calc,shadows.blur,shapes}
\tikzset{
    add path/.style = {
        decoration={show path construction,
            moveto code={
                \xdef\savedpath{\savedpath (\tikzinputsegmentfirst)}
            },
            lineto code={
                \xdef\savedpath{\savedpath -- (\tikzinputsegmentlast)}
            },
            curveto code={
                \xdef\savedpath{\savedpath .. controls (\tikzinputsegmentsupporta) and (\tikzinputsegmentsupportb) ..(\tikzinputsegmentlast)}
            },
            closepath code={
                \xdef\savedpath{\savedpath -- cycle}
            }
        },
        decorate
    },
    store path/.style = {add path},
    store path/.prefix code={\xdef\savedpath{}},
    callouts/.style={
        store path,
        append after command={
            foreach \target in {#1}{
            let \p1=($(\target.center)-(callout)$),\n1={atan2(\y1,\x1)+180}
            in
                ($(callout)!2pt!-90:(\target.center)$)--(\target.\n1) --
                ($(callout)!2pt!90:(\target.center)$)
            } \savedpath
        },
        alias=callout
    },
    custom style/.style={fill=blue!20,text=},
}
\begin{document}
\begin{tikzpicture}[
[baserect/.style={text width=0.5cm,align=left,draw,},
diam/.style={diamond,draw,align=left,text width=1cm,inner sep=1.5pt,fill=yellow,text=white,minimum size=2cm},
basecirc/.style={circle,draw,align=center,text width=1.5cm},
circ/.style={basecirc,fill=blue!60,text=black}]     
\node [diam] (1) {asdf};
\node [circ, right=5 of 1] (2) {asdf};
\node [diam, below=2 of 2] (3) {asdf};
\path[custom style] (3,1) node[callouts={1,2,3}]{blah blah};
\end{tikzpicture} 
\end{document}

在此处输入图片描述

相关内容