LaTeX 中用 TikZ 画八卦符号

LaTeX 中要显示八卦符号需要特殊的字体, 输入还需要 Unicode 码. 于是结合 TikZ 以及其他的四个宏包新定义了几个命令, 用来画太极阴阳, 两仪四象八卦和六十四卦的符号, 整理为一个小宏包 ( 已发于 CTAN: https://www.ctan.org/pkg/tikz-bagua 和 GitHub: https://github.com/duplli/tikz-bagua ). 该宏包依赖的宏包为

\RequirePackage{tikz}
\RequirePackage{xstring}
\RequirePackage{bitset}
\RequirePackage{xparse}
\RequirePackage{xintexpr}

核心代码就五个定义, 最后一个可选参数均为放缩系数.

%%\taiji[<scale>]
\newcommand\taiji[1][0.816]{% taiji yinyang
  \begin{tikzpicture}[baseline=-0.3em,scale=#1]
    \draw (0,0) circle (0.5em);
    \fill (0,-0.5em) arc (270:90:0.25em) arc (-90:90:0.25em) arc (90:270:0.5em);
    \fill (0,-0.25em) circle (0.05em);
    \fill [fill=white] (0,0.25em) circle (0.05em);
  \end{tikzpicture}%
}

%%\drawliangyi[<yshift>]{<0 or 1>}
\newcommand\drawliangyi[2][0]{%
  \ifnum #2=0 \draw [thick] (0,#1) -- (1em/3,#1) (2em/3,#1) -- (1em,#1)%;%
  \else%
    \ifnum #2=1 \draw [thick] (0,#1) -- (1em,#1)%;%
    \else \node {Error!}%
    \fi%
  \fi%
}

%%\liangyi{<0 or 1>}[<scale>]
\NewDocumentCommand\liangyi{mO{1}}{%
  \IfInteger{#1}{%
    \xintifboolexpr{#1 = 0 || #1 = 1}{%
      \begin{tikzpicture}[baseline=-0.3em,scale=#2]%
        \drawliangyi{#1};%
    \end{tikzpicture}}{\@latex@error{Error! Please check whether \#1 is 0 or 1.}{}}%
  }{\@latex@error{Error! Please check whether \#1 is integer.}{}}%
}

%%\sixiang{<binary>}[<scale>]
%%\sixiang*{<decimal>}[<scale>]
\NewDocumentCommand\sixiang{smO{1}}{% \sixiang{11}=\sixiang*{3}
  \IfInteger{#2}{% begin of if #2 is an integer
    \IfBooleanTF#1%
    {\xintifboolexpr{#2 >= 0 && #2 < 4}% begin of If a star is seen
      {\bitsetSetDec{sixiangdec}{#2}%
        \begin{tikzpicture}[baseline=-0.5em,scale=#3]%[baseline=-0.225em] 
          \foreach \j in {1,0}
          {
            \drawliangyi[-\j*0.408em]{\bitsetGet{sixiangdec}{\j}};
          }
      \end{tikzpicture}}{\@latex@error{Error! Please check whether 0<=\#1<4.}{}}%
    }% end of If a star is seen
    {\StrLen{#2}[\lengthforbinary]%begin of binary
      \xintifboolexpr{\lengthforbinary=1 || \lengthforbinary=2}{%
        \bitsetSetBin{sixiangbin}{#2}%
        \begin{tikzpicture}[baseline=-0.5em,scale=#3]%[baseline=-0.225em]
          \foreach \j in {1,0}
          {
            \drawliangyi[-\j*0.408em]{\bitsetGet{sixiangbin}{\j}};
          }
        \end{tikzpicture}%
      }{\@latex@error{Error! Please check whether 0<=\#1<=11.}{}}%end of binary
    }%     If no star is seen
  }% end of if #2 is an integer
  {\@latex@error{Error! Please check whether \#1 is integer.}{}}% else #2 is not an integer
}

%%\bagua{<binary>}[<scale>]
%%\bagua*{<decimal>}[<scale>]
\NewDocumentCommand\bagua{smO{1}}{% \bagua{101}=\bagua*{5}
  \IfInteger{#2}{% begin of if #2 is an integer
    \IfBooleanTF#1%
    {%% begin of If a star is seen
      \bitsetSetDec{baguadec}{#2}%
      \xintifboolexpr {#2 >= 0 && #2 <8}
      {%
        \begin{tikzpicture}[baseline=-0.714em,scale=#3]
          \foreach \j in {2,1,0}
          {
            \drawliangyi[-\j*0.408em]{\bitsetGet{baguadec}{\j}};
          }
        \end{tikzpicture}%
      }%
      {\@latex@error{Error! Please check whether 0<=\#1<8.}{}}%
    }%% end of If a star is seen
    {%% begin of If no star is seen
      \bitsetSetBin{baguabin}{#2}%
      \StrLen{#2}[\lengthforbinary]%
      \xintifboolexpr{\lengthforbinary > 0 && \lengthforbinary <4}%
      {%
        \begin{tikzpicture}[baseline=-0.714em,scale=#3]
          \foreach \j in {2,1,0}
          {
            \drawliangyi[-\j*0.408em]{\bitsetGet{baguabin}{\j}};
          }
        \end{tikzpicture}%
      }%
      {\@latex@error{Error! Please check whether 0<=\#1<1000.}{}}%
    }%% end of If no star is seen
  }% end of if #2 is an integer
  {\@latex@error{Error! Please check whether \#1 is integer.}{}}% else #2 is not an integer
}

%%\Bagua[<2 default, 8>]{<binary, octal>}[<scale>]
%%\Bagua*{<decimal>}[<scale>]
\NewDocumentCommand\Bagua{sO{2}mO{1}}{% \bagua{101110}=\bagua[8]{56}=\bagua*{46}
  \IfInteger{#3}{% begin of if #3 is an integer
    \IfBooleanTF#1%
    {%% begin of If a star is seen
      \bitsetSetDec{baguadec}{#3}%
      \xintifboolexpr {#3 >= 1 && #3 <64}%
      {%
        \begin{tikzpicture}[baseline=-0.714em,scale=#4]
          \foreach \j in {5,4,...,0}
          {
            \drawliangyi[-\j*0.1632em]{\bitsetGet{baguadec}{\j}};
          }
        \end{tikzpicture}%
      }{\@latex@error{Error! Please check whether 0<=\#2<64.}{}}%
    }%% end of If a star is seen
    {%% begin of If no star is seen
      \ifnum#2=2%
      \bitsetSetBin{baguabin}{#3}%
      \StrLen{#3}[\lengthforbinary]%
      \xintifboolexpr{\lengthforbinary >= 1 && \lengthforbinary <7}%
      {%
        \begin{tikzpicture}[baseline=-0.714em,scale=#4]
          \foreach \j in {5,4,...,0}
          {
            \drawliangyi[-\j*0.1632em]{\bitsetGet{baguabin}{\j}};
          }
        \end{tikzpicture}%
      }{\@latex@error{Error! Please check whether 0<=\#2<1000000.}{}}%
      \else%
      \ifnum#2=8%
      \bitsetSetOct{baguaoct}{#3}%
      \StrLen{#3}[\lengthforoct]%
      \xintifboolexpr{\lengthforoct =1 || \lengthforoct =2}%
      {%
        \begin{tikzpicture}[baseline=-0.714em,scale=#4]
          \foreach \j in {5,4,...,0}
          {
            \drawliangyi[-\j*0.1632em]{\bitsetGet{baguaoct}{\j}};
          }%
        \end{tikzpicture}%
      }{\@latex@error{Error! Please check whether 0<=\#2<100.}{}}%
      \else{\@latex@error{Error! Please check whether \#1 is default (2) or 8.}{}}\fi%
      \fi%
    }%% end of If no star is seen
  }% end of if #3 is an integer
  {\@latex@error{Error! Please check whether \#2 is integer.}{}}% else #3 is not an integer
}

其中 \sixiang 调用二进制数字, \sixiang* 调用十进制数字, \bagua, \Bagua 类似. 此外 \Bagua[8]{<oct>} 支持调用八进制数字. 上图的代码如下:

  \begin{tikzpicture}
    \foreach \j in {7,6,...,0}
    {
      \foreach \k in {7,6,...,0}
      {
        \node at (7*1.25-1.25*\k-0.3,1.5*\j-0.5) {\pgfmathparse{int(8*\j+\k)}\pgfmathresult};
        \node at (7*1.25-1.25*\k+0.3,1.5*\j-0.5) {\j\k};
        \node at (7*1.25-1.25*\k,1.5*\j+0.5) {\nbinary{3}{\j}\nbinary{3}{\k}};
        \node at (7*1.25-1.25*\k,1.5*\j) {\Bagua[8]{\j\k}[1.5]};
      }
    }
  \end{tikzpicture}

其中每一卦上一行是对应的二进制数字, 下一行左右分别对应十进制和八进制数字.

鉴于个人水平所限, 不足之处难免, 欢迎各位斧正!