生成具有平滑边缘的图形?

生成具有平滑边缘的图形?

有没有办法使用 TeX 本身(最好使用 TikZ)来生成这些图形?如果是,那么我还想在节点旁边添加标签,而不是使用图例。

在此处输入图片描述

这是我正在阅读的一篇论文的截图,我更喜欢使用 TeX 来创建它们,而不是使用一些外部工具。

编辑

我读了答案这里但我想在线上添加“十字”,而不是指向十字必须存在的位置的灰色线。此外,我不知道如何将十字更改为上面绘制的图表中给出的不同符号。

答案1

您可以使用to角度作为线进入和离开节点的参数。

\draw (from-node) to[out=angle at from-node,in=angle at to-node] (to-node);

这些角度是从 x 轴正方向测量的。

在此处输入图片描述

\documentclass[border=1mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes}
\begin{document}
\tikzset
  {dest/.style={circle,draw,minimum width=1mm,inner sep=0mm},
   start/.style={diamond,fill,draw,minimum width=1mm, minimum height=1mm,inner sep=0mm},
   terminal/.style={circle,draw,minimum width=1.5mm,inner sep=0mm,label={[label distance=-2.75mm]{\tiny+}}}
  }
\begin{tikzpicture}
  \node[start,label={[right]:$s$}] (s) at (0,0) {};
  \node[dest,label={[left]:$d_1$}] (d1) at (-1,0.5) {};
  \node[dest,label={[right]:$d_2$}] (d2) at (0.3,0.6) {};
  \node[dest,label={[right]:$d_3$}] (d3) at (0,1.5) {};
  \node[dest,label=$d_4$] (d4) at (-1,2) {};
  \node[terminal,label={[left]:$t$}] (t) at (-0.9,1.3) {};
  \draw (s) to[out=170,in=-90] (d1);
  \draw (d1) to[out=70,in=-100] (d2);
  \draw (d2) to[out=100,in=-60] (d3);
  \draw (d3) to[out=120,in=30] (d4);
  \draw (d4) to[out=-110,in=100] (t);
\end{tikzpicture}
\end{document}

答案2

为了实现更加自动化的平滑连接,减少人工劳动,您可以使用\draw [smooth] plot coordinates {(0,0) (1,0) (1,0) (1,1)};tension=1.5指定直线的紧密度。参见这个答案有关此类命令的功能的更多详细讨论。

使用expl3(我加载了xparse并使用\NewDocumentCommand而不是\newcommand但该部分可以用 LaTeX2e 完成)我定义了一个新命令,该命令将一组坐标以;(这可以是任何合理的分隔符,我使用;over,因为坐标自然有(a,b)描述)分隔作为单个输入。然后将坐标拆分成一个seq变量( ),从中提取它们进行绘图。以及一个可选参数,用于设置绘图的\l__banachtarski_coords_seq值。tension

据我所知TikZ选项中不提供mark firstmark lastmark middle类型命令\draw plot,因此我首先在所有点之间绘制一条平滑的线,然后使用一种相当低效的方法放置标记,即在第一个坐标处放置一个标记,在第二个坐标处放置一个标记,使用不同的标记,在此过程中将\draw plot [smooth, tension=1.5] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };它们从\l__banachtarski_coords_seq

\seq_pop_left:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=diamond*,mark~options={fill=black}] coordinates {
  \l__banachtarski_temp_tl
};

\seq_pop_right:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=oplus*,mark~options={fill=gray}] coordinates {
  \l__banachtarski_temp_tl
};

然后用第三个标记绘制剩余的中间坐标

\draw plot [only~marks,mark=*,mark~options={fill=gray}] coordinates {
  \seq_use:Nn \l__banachtarski_coords_seq { ~ }
};

only~marks(只画标记,不画连接线)必须使用,而不是only marks因为这一切都发生在内部\ExplSyntaxOn ... \ExplSyntaxOff尽管它可能仅需要用于绘制最终的一组标记。

因此(使用与gernot 的回答它可以以更大的努力提供更精细的控制)可以生成 在此处输入图片描述

\documentclass{article}
\usepackage{xparse}
\usepackage{tikz}
\usetikzlibrary{plotmarks}

\ExplSyntaxOn
\seq_new:N \l__banachtarski_coords_seq
\tl_new:N \l__banachtarski_temp_tl

\NewDocumentCommand \smoothgraph { O{1} m }
{
\seq_set_split:Nnn \l__banachtarski_coords_seq { ; } { #2 }

\draw plot [smooth, tension=#1] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };

\seq_pop_left:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=diamond*,mark~options={fill=black}] coordinates { \l__banachtarski_temp_tl };

\seq_pop_right:NN \l__banachtarski_coords_seq \l__banachtarski_temp_tl
\draw plot [only~marks,mark=oplus*,mark~options={fill=gray}] coordinates { \l__banachtarski_temp_tl };

\draw plot [only~marks,mark=*,mark~options={fill=gray}] coordinates { \seq_use:Nn \l__banachtarski_coords_seq { ~ } };
}

\ExplSyntaxOff

\begin{document}
\begin{tikzpicture}
    \smoothgraph{(0,0);(-1,0.5);(0.3,0.6);(0,1.5);(-1,2);(-0.9,1.3)}
\end{tikzpicture}
\begin{tikzpicture}
    \smoothgraph[2]{(0,0);(-1,0.5);(0.3,0.6);(0,1.5);(-1,2);(-0.9,1.3)}
\end{tikzpicture}
\end{document}

相关内容