语法

语法

我更喜欢使用 TeX 内部创建的图形,但我只知道非常耗费人力的方法。下面使用一些颜色和附加符号创建 (6,3,2,4,1,5) 的排列图。

我正在考虑一个需要大量此类数字的项目。编写宏来创建此类东西可行吗?还有其他建议可以让这个过程不那么痛苦吗?

\[ \begin{matrix}[cc|cccccc|c]  
& & & & & & {\color{blue}\downarrow} & {\color{blue}\downarrow} & S \\ \hline  
& 6 & {\color{red}\newmoon} & & & & & & {\color{red}\leftarrow} \\   
{\color{blue}*} &5 & & & & & &  {\color{blue}\newmoon} &  \\   
& 4 & & & & {\color{red}\newmoon} & & & {\color{red}\leftarrow} \\   
& 3 & & {\color{red}\newmoon} & & & & & {\color{red}\leftarrow} \\  
& 2 & & & \fullmoon & & & &  \\ 
{\color{blue}*} & 1 & & & & & {\color{blue}\newmoon}  & & \\ \hline
& & 1 & 2 & 3 & 4 & 5 & 6 & \\
&  & {\color{red}*} & {\color{red}*} & & {\color{red}*} & & &
\end{matrix} \]

在此处输入图片描述

答案1

我很想使用,matrix of nodes但我的解决方案借鉴了 Jake 的精彩代码使用 TikZ 的中国跳棋棋盘这有效地手动设置了matrix of nodes

此解决方案需要tikzxstring包。

语法

例如,您可以使用下面的代码

\drawpermutate{blue/{1/1,3/2}/left,red/{3/4,2/3}/right}

截屏

\drawpermutate{green/{1/1,3/5,4/2}/left,orange/{3/4,2/3}/right}

在此处输入图片描述

你会注意到,论点的每个部分都包含三个部分:

  • colour:这应该是不言自明的
  • {list of coordinates}:请注意,这需求分组{},每个有序对(x,y)需要写成x/y
  • left or right:这可以是left或 ,right具体取决于您希望图例如何显示。实际上,它可以是left或任何其他内容 - 如果不是left,它将显示在右侧(和下方)。

代码

这是一个完整的 MWE,你可以试试;代码的注释相当详细 - 它基本上使用几个循环来设置nodes,然后在每个节点(圆圈、箭头或 *)上执行适当的操作。

% arara: pdflatex
% !arara: indent: {overwrite: true}
\documentclass{standalone}

\usepackage{tikz}
\usepackage{xstring}

\newcommand{\drawpermutate}[1]{%
    \begin{tikzpicture}
        % setup the nodes
        \foreach [evaluate=\i as \x using int(\i-1)]\i in {0,1,...,8}
        {
            \foreach [evaluate=\j as \y using int(\j-1)] \j in {0,1,...,8}
            {
                %      \node at (\i,\j)[name=perm-\x-\y,label=\x-\y]{};
                \node at (\i,\j)[name=perm-\x-\y,]{};
            }
        }

        % draw numbers 1 to 6 in both x and y direction
        \foreach \i in {1,...,6}
        {
            \node at (perm-\i-0.center){\i};
            \node at (perm-0-\i.center){\i};
        }
        \node at (perm-7-7.center){$S$};

        % vertical lines
        \draw ([xshift=-5mm]perm-1--1.south west)--([xshift=-5mm]perm-1-7.north west);
        \draw ([xshift=-5mm]perm-7--1.south west)--([xshift=-5mm]perm-7-7.north west);
        % horizontal lines
        \draw ([yshift=5mm]perm--1-0.south west)--([yshift=5mm]perm-7-0.south east);
        \draw ([yshift=5mm]perm--1-6.south west)--([yshift=5mm]perm-7-6.south east);

        % draw user input
        \foreach \mystyle/\coords/\leftorright in {#1}
        {
            \foreach \x/\y in \coords
            {
                \node[circle,fill=\mystyle,draw=\mystyle] at (perm-\x-\y){};
                \IfStrEq{\leftorright}{left}{%
                    \node[\mystyle] at (perm--1-\y){*};
                    \node[\mystyle] at (perm-\x-7){$\downarrow$};
                }
                {% otherwise put it on the right
                    \node[\mystyle] at (perm-7-\y){$\leftarrow$};
                    \node[\mystyle] at (perm-\x--1){*};
                }
            }

        }

    \end{tikzpicture}
}

\begin{document}

%\drawpermutate{blue/{1/1,3/5,4/2}/left,red/{3/4,2/3}/right}

\drawpermutate{green/{1/1,3/5,4/2}/left,orange/{3/4,2/3}/right}

\end{document}

答案2

TikZ 不是强制性的:-)

在此处输入图片描述

\documentclass{article}
\usepackage{color}
\makeatletter

\def\pdiag#1{{%
\setlength\unitlength{15pt}%
\begin{picture}(10,10)(-2,-2)%
\put(0,-2){\line(0,1){10}}%
\put(7,-2){\line(0,1){10}}%
\put(-2,-0){\line(1,0){10}}%
\put(-2,7){\line(1,0){10}}%
\put(7.2,7){S}%
\count@\z@
\@for\yc:=#1\do{%
\expandafter\ycdef\yc
\advance\count@\@ne
\put(-1,\count@){\the\count@}%
\put(\count@,-1){\the\count@}%
\put(\count@,\y){\if r\c\color{red}\else\if b\c\color{blue}\fi\fi
                  \circle*{.3}}%
\if r\c
\put(\count@,-2){\color{red}$\ast$}%
\put(7,\y){\color{red}$\leftarrow$}%
\fi
\if b\c
\put(-2,\y){\color{blue}$\ast$}%
\put(\count@,7.1){\color{blue}$\downarrow$}%
\fi
}%
\end{picture}}}

\def\ycdef#1#2{\def\y{#1}\def\c{#2}}
\begin{document}

\pdiag{6r,3r,2x,4r,1b,5b}


\end{document}

答案3

在此处输入图片描述

使用Asymptote模块permdiag.asy,这个漂亮的小排列游戏的排版可以完全自动化。处理以下文件permdiag-test.asy

import permdiag;
permDiag pd=permDiag(new int[]{6,3,2,4,1,5});

for(int i=1;i<=pd.n;++i){
  shipout("diag"+format("%02d",i),pd.board(i));
}

结果asy -f pdf permdiag-test.asy为 6 个文件diag01.pdf.. diag06.pdf,它们被合并在一起

\documentclass[a4paper]{article}
\usepackage{graphicx}
\begin{document}
\noindent%
\includegraphics[scale=1]{diag00.pdf}\quad 
\includegraphics[scale=1]{diag01.pdf}\quad 
\includegraphics[scale=1]{diag02.pdf}\\[10mm]
\noindent%
\includegraphics[scale=1]{diag03.pdf}\quad 
\includegraphics[scale=1]{diag04.pdf}\quad 
\includegraphics[scale=1]{diag05.pdf} 
\end{document}

这是permdiag.asy处理permDiag类的 main 函数:

struct permDiag{
  int n;
  int[] perm;
  int[] dotState;
  int[][] tperm;

  picture boardPic;
  guide dotShape;
  pen[] dotFill;

  void drawNumbers(){
    for(int i=0;i<n;++i){
      label(boardPic,string(i+1),(i,-1));
      label(boardPic,string(n-i),(-1,n-1-i));
    }
  }

  void drawArrows(){
    for(int i=0;i<n;++i){
      if(dotState[i]>0){
        if(dotState[i]==1){
          label(boardPic,"$\leftarrow$",(n+0.5,tperm[i][0]-1));
        }else{
          label(boardPic,"$\downarrow$",(tperm[i][2]-1,n+0.5));
        }  
      }  
    }
  } 

  void drawStars(){
    for(int i=0;i<n;++i){
      if(dotState[i]>0){
        if(dotState[i]==2){
          label(boardPic,"*",(-2,tperm[i][0]-1));
        }else{
          label(boardPic,"*",(tperm[i][3]-1,-2));
        }  
      }  
    }
  } 

  void drawLines(){
    draw(boardPic,(-2.5,-0.5)--(n+1.5,-0.5));
    draw(boardPic,(-2.5,n-0.5)--(n+1.5,n-0.5));
    draw(boardPic,(-0.5,-2.5)--(-0.5,n+1.5));
    draw(boardPic,(n-0.5,-2.5)--(n-0.5,n+1.5));
  }


  void play(int hstep){
    erase(boardPic);
    int tmp;
    int redblu=0;
    for(int i=0;i<n;++i){
      tperm[i][0]=perm[i];
      tperm[i][4]=i+1;      
    }
    dotState=array(n,0); 
    for(int i=0;i<hstep;++i){
      for(int j=n-1;j>i;--j){
        if(tperm[j][redblu]>tperm[j-1][redblu]){
          tmp=tperm[j][redblu];
          tperm[j][redblu]=tperm[j-1][redblu];
          tperm[j-1][redblu]=tmp;
          tmp=tperm[j][1-redblu];
          tperm[j][1-redblu]=tperm[j-1][1-redblu];
          tperm[j-1][1-redblu]=tmp;          
        }
      }
      dotState[i]=1+redblu;
      redblu=1-redblu;
    }
  }

  picture board(int move){
    assert(move>=0 && move<=n);
                      //  move number, 0 = initial state, 
                      //   odd - after red move
                      //  even - after blu move
    play(move);
    for(int i=0;i<n;++i){       
      filldraw(boardPic,shift(tperm[i][5]-1,tperm[i][0]-1)*dotShape,dotFill[dotState[i]]);
    }
    drawNumbers();
    drawArrows();
    drawStars();
    drawLines();
    label(boardPic,"$\mathcal{S}$",(n+0.5,n+0.5));
    return boardPic;
  }

  void operator init(int[] perm){
    assert(perm.length>0);
    this.n=perm.length;
    this.perm=copy(perm);
    this.dotState=array(n,0);
    this.dotShape=scale(0.382)*unitcircle;
    this.dotFill=new pen[]{lightyellow,red,blue};
    this.tperm=new int[n][6];
    boardPic.size(20*n);
  }
} 

//// Example:
//
//  import permdiag;
//  permDiag pd=permDiag(new int[]{6,3,2,4,1,5});
//
//  for(int i=0;i<=pd.n;++i){
//    shipout("diag"+format("%02d",i),pd.board(i));
//  }
//

编辑:固定图片缩放以适应不同的 值n。例如permdiag-test2.asy

import permdiag;
permDiag pda=permDiag(new int[]{3,1,2,4});
permDiag pdb=permDiag(new int[]{9,19,17,1,8,13,18,11,10,4,5,7,2,3,15,16,12,6,20,14});
int i;
i=3;
shipout("diag-"+format("n%d-",pda.n)+format("%02d",i),pda.board(i));
i=12;
shipout("diag-"+format("n%d-",pdb.n)+format("%02d",i),pdb.board(i));

处理asy -f pdf permdiag-test2.asy结果见两张图片, diag-n4-03.pdf以及 diag-n20-12.pdf

在此处输入图片描述

在此处输入图片描述

答案4

如果你问是否可以写类似的东西

\permdiag(6,3,2,4,1,5)

并获得类似的图片,答案是肯定的。但是,需要额外的规则。特别是,我认为红色圆圈表示数字向上移动,蓝色圆圈表示数字向下移动,白色圆圈表示数字不变,但事实并非如此,因为 3 而不是 4 是白色的。如果这些规则在比较数字方面很容易,那么制作这样的宏就是一项练习。

例如(这只是一个草图,没有图形,只有一些简单的规则)

\documentclass[a4paper,11pt,leqno]{article}

\begin{document}

\newcount\pei
\newcount\peii
\newcount\peiii

\def\perm(#1,#2,#3){\pei#1 \peii#2 \peiii#3
\ifcase\pei\or100\or010\or001\fi\endgraf
\ifcase\peii\or200\or020\or002\fi\endgraf
\ifcase\peiii\or300\or030\or003\fi\endgraf
}

\perm(1,2,3)

\perm(3,1,2)
\end{document}

在此处输入图片描述

相关内容