在 tikz 的“to”路径中设置“in”,而不是“out”

在 tikz 的“to”路径中设置“in”,而不是“out”

如果我在 tikz 中使用这样的代码,它就会按我预期的方式工作:

\draw (0,1) to[out=0, in=180] (1,0);

在此处输入图片描述

但是,如果我设置in但没有设置out,那么奇怪的事情就会发生:

\draw (0,1) to[in=180] (1,0);

在此处输入图片描述

我期望的是,这条线一开始会朝着目标节点前进,然后弯曲,最后变成水平状态,类似于下面的一条曲线:

在此处输入图片描述

然而,曲线却以大约 45 度的角度开始向上移动,这似乎有点不合逻辑。

所以问题是,首先这里发生了什么,其次有没有办法实现我想要的?

这是我正在开发的一个小库,所以如果有解决方案,我需要它能够工作并且看起来合理,适用于任何端点位置,而无需任何手动微调。在我上面画的两条曲线中,左边的那条看起来比另一条好得多。

如果这在某些明显的地方描述,请原谅 - 因为搜索“in”,“out”和“to”等术语非常困难。

以下是完整的 MWE 代码:

\documentclass{article}

\usepackage{tikz}

\begin{document}

\begin{tikzpicture}
\draw (0,1) to[out=0, in=180] (1,0);
\end{tikzpicture}

\begin{tikzpicture}
\draw (0,1) to[in=180] (1,0);
\end{tikzpicture}

\end{document}

答案1

感觉就像你想定义一条仅取决于in。由于在 TikZ 中,曲线路径是三次贝塞尔曲线,因此仅指定角度是不够的。所以我们需要找出另一个控制点来给出合理的曲线。以下代码以以下方式执行此操作。我们首先定义第二控制点与终点之间的指定角度,距离为起点和终点之间间距的三分之一。然后我们定义第一个控制点,使其意味着路径从起点向第二个控制点的方向离开(同样距离为间距的三分之一 - 三分之一适用于三次贝塞尔曲线)。

最后,将其组合成一个to路径以方便使用。它确实使用calc库来简化计算,但可以通过添加更多代码将其删除。

\documentclass{article}
%\url{https://tex.stackexchange.com/q/609102/86}
\usepackage{tikz}
\usetikzlibrary{calc}

\tikzset{
  only in/.style={
  to path={
  let
  \p1 = ($ (\tikztotarget) - (\tikztostart) $)
  in
   .. controls 
  ($(\tikztostart)!{veclen(\x1,\y1)/3}!($(\tikztotarget)+(#1:{veclen(\x1,\y1)/3})$)$)
  and
  ($(\tikztotarget)+(#1:{veclen(\x1,\y1)/3})$)
  .. (\tikztotarget)
  }
  }
  }

\begin{document}

\begin{tikzpicture}
\draw (0,1) to[only in=180] (1,0);
\end{tikzpicture}

\end{document}

仅指定角度的曲线路径

(分辨率较差是因为截取的是放大的网页。)

looseness可以使用与通常路径上的键类似的键来定制 1/3 的因子to

答案2

以下方法尽可能轻微地修改代码库。

它允许您in looseness与一起使用in,并使用传统的计算来计算第二个控制点。然后,它用于out looseness定义第一个控制点,如下所示

($ the starting point ! out looseness ! the second control point $)

您可以将out/ from/startin/ to/ end/交换target 来定义only out

\documentclass{article}
\usepackage{tikz}
    \usetikzlibrary{calc}
\makeatletter
\tikzset{
    only in/.code={%
        \tikzset{in=#1}%
        \def\tikz@to@start@compute@looseness{%
            \def\tikz@computed@start{($%
                (\tikztostart)% the starting point
                !\tikz@to@out@looseness!% you choose the looseness
                \tikz@computed@end% second control point (TikZ will compute it)
            $)}%
        }%
        \let\tikz@to@start@compute=\tikz@to@start@compute@looseness
        % ^ There is an \ifx that tests if \...@compute
        % ^ is one of the predefined ones.
        % ^ Since we redefine \...@looseness, this \ifx is no longer true.
        % ^ I added a \let to honor that \ifx and make the hack works
    }
}
\begin{document}
\tikz{
    \foreach\A in{1,2,3,4}{
        \foreach\B in{1,2,3,4}{
            \draw(\A*3,\B*3)
                to[only in=180,out looseness=\A/4,in looseness=\B/2]
                +(2.5,-2.5);
        }
    }
}
\tikz{
    \foreach\A in{1,2,3,4}{
        \foreach\B in{1,2,3,4}{
            \draw(\A*3,\B*3)node(S){START}+(2.5,-2.5)node(T){TARGET}
                (S)to[only in=180,out looseness=\A/4,in looseness=\B/2](T)
            ;
        }
    }
}
\end{document}

相关内容