新答案

新答案

我想绘制一些盐的示意图,用于教学目的。该图显示了一个可以使用下面的 metapost 代码生成的示例。我想通过两种方式改进绘图:第一)将矩形的角弄圆;第二)改进三角形槽,即交互区域(更好的对齐和其他教学改进)

代码可以生成各种盐:Salt(anionCharge, cationCharge, anionName, cationName);

在此处输入图片描述

\starttext

\startalignment[middle]
\dontleavehmode
\startMPcode
vardef Ionic (expr p,  n, w, o) = 
pair vec ; path pat;
 if o==1:
 pat := for i=1 upto n: (w,i)--(w,i+.2)--(w/2,i+.35)--(w, i+.60)--endfor(w,n+.8)--(w/2-.2,n+.8)--(w/2-.2,1)--cycle;
else:
 pat := for i=1 upto n: (w,i)--(w,i+.2)--(w/2,i+.35)--(w, i+.60)--endfor(w,n+.8)--(w+w/2+.2,n+.8)--(w+w/2+.2,1)--cycle;
fi;
 pat xscaled 40 yscaled 40
enddef;

def Salt(expr anionCharge, cationCharge, anionName, cationName) =
 path catiao, aniao;
 numeric ania, catia;
 ania := anionCharge; catia := cationCharge;
 catiao := Ionic((0,0),catia,1,1);
   for i=1 upto ania:
      draw catiao shifted (0,(i-1)*40*catia) withpen pencircle scaled 2pt withcolor red;
      fill catiao shifted (0,(i-1)*40*catia) withcolor 0.7white;
      label.lft(cationName, (0,i*40*catia));
   endfor;
 aniao := Ionic((0,0),ania,1,0);
   for i=1 upto catia:
      draw aniao shifted (10,(i-1)*40*ania) withpen pencircle scaled 2pt withcolor blue;
      fill aniao shifted (10,(i-1)*40*ania) withcolor .9white;
      label.rt(anionName, (85,i*40*ania));
   endfor;
enddef;

Salt(3,2,btex PO$_4^{3-}$ etex, btex Ca$^{2+}$ etex);
\stopMPcode
\stopalignment


\stoptext

答案1

新答案

实际上我更喜欢圆形而不是矩形

\tikzset{
    c/.style={violet},
    a/.style={olive},
    er/.store in=\er,er=.2,
    nodes={white,font=\Huge}
}
\def\msm#1#2{\pgfmathsetmacro#1{#2}\xdef#1{#1}}
\makeatletter
\def\salt{\pgfutil@ifnextchar[{\saltopt}{\saltopt[]}}
\def\saltopt[#1]#2^#3+#4Å#5^#6-#7Å{{
    \tikzset{#1,#2/.try,#5/.try}
    \msm\cc{max(#3.0,1)}\msm\ac{max(#6.0,1)}
    \msm\tt{\cc*\ac/gcd(\cc,\ac)}\msm\htt{floor(\tt/2)+1}
    \msm\cn{\tt/\cc}\msm\an{\tt/\ac}
    \msm\cr{#4}\msm\ar{#7}\msm\tr{\ar+\cr}
    % prepare center ions, four cases
    \ifodd\an\ifodd\cn % both odd
        \xdef\cx{-\cr}\xdef\cy{0}\xdef\ax{\ar}\xdef\ay{0}
        \fill[c](\cx,\cy)circle(\cr)node(C0){$\mathrm{#2}^{#3+}$};
        \fill[a](\ax,\ay)circle(\ar)node(A0){$\mathrm{#5}^{#6-}$};
    \else % anion number odd
        \msm\cx{\ar-sqrt(\tr*\tr-\cr*\cr)}\msm\cy{\cr}\xdef\ax{\ar}\xdef\ay{0}
        \fill[c](\cx,\cy)circle(\cr)node(C+0){$\mathrm{#2}^{#3+}$}(\cx,-\cy)circle(\cr)node(C-0){$\mathrm{#2}^{#3+}$};
        \fill[a](\ax,\ay)circle(\ar)node(A0){$\mathrm{#5}^{#6-}$};
    \fi\else % cation number odd
        \xdef\cx{-\cr}\xdef\cy{0}\msm\ax{sqrt(\tr*\tr-\ar*\ar)-\cr}\msm\ay{\ar}
        \fill[c](\cx,\cy)circle(\cr)node(C0){$\mathrm{#2}^{#3+}$};
        \fill[a](\ax,\ay)circle(\ar)node(A+0){$\mathrm{#5}^{#6-}$}(\ax,-\ay)circle(\ar)node(A-0){$\mathrm{#5}^{#6-}$};
    \fi
    % draw ions and electrons
    \xdef\ao{0}\xdef\co{0}\xdef\eo{0}
    \foreach\e in{\htt,...,\tt}{
        \msm\am{mod(\e,\ac)}\msm\cm{mod(\e,\cc)}
        % need new electron
            \msm\para{\ar+(2*\eo+1)*\er}
            \msm\ex{\ax+\para*(\cx-\ax)/\tr}
            \msm\ey{\ay+\para*(\cy-\ay)/\tr}
            \msm\eo{int(\eo+1)}
            \ifdim\ey pt=0pt
                \fill[a](\ex,\ey)circle(\er)node(e00\eo){};
                \ifodd\tt\ifnum\eo>1
                    \msm\eo{int(\eo+1)}
                    \fill[a](\ex-2*\er,\ey)circle(\er)node(e00\eo){};
                \fi\else
                    \msm\eo{int(\eo+1)}
                    \fill[a](\ex-2*\er,\ey)circle(\er)node(e00\eo){};
                \fi
            \else
                \fill[a](\ex,\ey)circle(\er)node(e+\ao+\co+\eo){}(\ex,-\ey)circle(\er)node(e-\ao-\co-\eo){};
            \fi
        \ifdim\e pt<\tt pt
        \ifdim\am pt=0pt % need new anion
            \msm\para{2*\ar*\ar/\tr}
            \msm\perp{sqrt(4*\ar*\ar-\para*\para)}
            \msm\axnew{\ax+(\para*(\cx-\ax)+\perp*(\cy-\ay))/\tr}
            \msm\aynew{\ay+(\para*(\cy-\ay)+\perp*(\ax-\cx))/\tr}
            \xdef\ax{\axnew}\xdef\ay{\aynew}
            \msm\ao{int(\ao+1)}\xdef\eo{0}
            \fill[a](\ax,\ay)circle(\ar)node(A+\ao){$\mathrm{#5}^{#6-}$}(\ax,-\ay)circle(\ar)node(A-\ao){$\mathrm{#5}^{#6-}$};
        \else\ifdim\cm pt=0 pt % need new cation
            \msm\para{2*\cr*\cr/\tr}
            \msm\perp{sqrt(4*\cr*\cr-\para*\para)}
            \msm\cxnew{\cx+(\para*(\ax-\cx)+\perp*(\cy-\ay))/\tr}
            \msm\cynew{\cy+(\para*(\ay-\cy)+\perp*(\ax-\cx))/\tr}
            \xdef\cx{\cxnew}\xdef\cy{\cynew}
            \msm\co{int(\co+1)}\xdef\eo{0}
            \fill[c](\cx,\cy)circle(\cr)node(C+\co){$\mathrm{#2}^{#3+}$}(\cx,-\cy)circle(\cr)node(C-\co){$\mathrm{#2}^{#3+}$};
        \fi\fi\fi
    }
}}
\tikz{\salt Xk^ +2Å Cd^ -3Å}
\tikz{\salt Xk^2+2Å Cd^2-3Å}
\tikz{\salt Xk^3+2Å Cd^3-3Å}

\tikz{\salt Xk^1+2Å Cd^2-3Å}
\tikz{\salt Xk^2+2Å Cd^4-3Å}
\tikz{\salt Xk^3+2Å Cd^6-3Å}

\tikz{\salt Xk^ +2Å Cd^3-3Å}
\tikz{\salt Xk^ +2Å Cd^4-3Å}
\tikz{\salt Xk^ +2Å Cd^5-3Å}

\tikz{\salt Xk^2+2Å Cd^3-3Å}
\tikz{\salt Xk^2+2Å Cd^5-3Å}
\tikz{\salt Xk^2+2Å Cd^7-3Å}

盐的收集

\tikz{
    \salt                            Xk^2+3Å Cd^ -2Å
    \salt[shift={(12,0)}]            Xk^4+3Å Cd^3-2Å
    \salt[shift={(-4,15)},rotate=-60]Xk^6+3Å Cd^5-2Å
    \salt[shift={(-6,-18)},rotate=60]Xk^8+3Å Cd^7-2Å
}

巨大的盐

\tikz{\salt[rotate=90]Xk^29+12Å Cd^12-5Å}


调整离子大小的规范方法是直接在

\salt[er=.2]Xk^29+12Å Cd^12-5Å

其中12Å随后被翻译成12cm5cmÅ来自,你可能已经猜到了。要调整电子的大小,请传入er=.2选项。

由于我添加了一个可选参数\salt,因此您可以传递任何 TiZ 样式。如上所示,它可以是shift=rotate。它也可以是scale=c/.style=或颜色/字体规范。

此外,您还可以添加\tikzset{Xk/.style={c/.style=black}},以便每次Xk绘制时都将其涂成黑色。


旧答案

像这样?

\documentclass[tikz,border=9]{standalone}
\begin{document}
    \def\salt#1^#2+#3^#4-{
        \pgfmathsetmacro\cationcharge{max(0#2,1)}
        \pgfmathsetmacro\anioncharge{max(0#4,1)}
        \pgfmathsetmacro\totaltransfer{\cationcharge*\anioncharge/gcd(\cationcharge,\anioncharge)}
        \pgfmathsetmacro\halftransfer{max(\totaltransfer/2,2)}
        \pgfmathsetmacro\anionnumber{\totaltransfer/\anioncharge}
        \pgfmathsetmacro\cationnumber{\totaltransfer/\cationcharge}
        \pgfmathsetmacro\w{.1}
        \pgfmathsetmacro\x{.1}
        \pgfmathsetmacro\y{.2}
        \pgfmathsetmacro\z{.5}
        \tikz{
            % draw anion
            \foreach\c in{1,...,\cationnumber}
                \fill[rounded corners,yellow](-\w,\c*\cationcharge)+(0,-\x)rectangle node[black]{$\mathrm{#1}^{#2+}$}+(-\halftransfer,-\cationcharge+\x);
            % draw cation
            \foreach\a in{1,...,\anionnumber}
                \fill[rounded corners,lime](\w,\a*\anioncharge)+(0,-\x)rectangle node[black]{$\mathrm{#3}^{#4-}$}+(\halftransfer,-\anioncharge+\x);
            % draw transfer
            \foreach\e in{1,...,\totaltransfer}{
                \fill[white](-\w,\e-.5)+(0,\y)--+(-\z,0)--+(0,-\y);
                \fill[lime](\w,\e-.5)+(0,\y)--+(-\z,0)--+(0,-\y);
            }
        }
    }
    \salt Na^+Cl^-
    \salt Ca^2+Cl^-
    \salt Ca^2+SO_4^2-
    \salt Ca^2+PO_4^3-

或这个

\def\salt#1^#2+#3^#4-{
    \pgfmathsetmacro\cationcharge{max(0#2,1)}
    \pgfmathsetmacro\anioncharge{max(0#4,1)}
    \pgfmathsetmacro\totaltransfer{\cationcharge*\anioncharge/gcd(\cationcharge,\anioncharge)}
    \pgfmathsetmacro\halftransfer{max(\totaltransfer/2,2)}
    \pgfmathsetmacro\anionnumber{\totaltransfer/\anioncharge}
    \pgfmathsetmacro\cationnumber{\totaltransfer/\cationcharge}
    \pgfmathsetmacro\w{.1}
    \pgfmathsetmacro\x{.1}
    \pgfmathsetmacro\y{.1}
    \pgfmathsetmacro\z{.2}
    \tikz{
        % draw anion
        \foreach\c in{1,...,\cationnumber}
            \fill[rounded corners,yellow](-\w,\c*\cationcharge)+(0,-\x)rectangle node[black]{$\mathrm{#1}^{#2+}$}+(-\halftransfer,-\cationcharge+\x);
        % draw transfer
        \foreach\e in{1,...,\totaltransfer}{
            \fill[white](-\w,\e-.5)+(-\y,0)circle(\z);
            \fill[lime](\w,\e-.5)+(-\y,0)circle(\z);
        }
        % draw cation
        \foreach\a in{1,...,\anionnumber}
            \fill[rounded corners,lime](\w,\a*\anioncharge)+(0,-\x)rectangle node[black]{$\mathrm{#3}^{#4-}$}+(\halftransfer,-\anioncharge+\x);
    }
}
\salt Na^+Cl^-
\salt Ca^2+Cl^-
\salt Ca^2+SO_4^2-
\salt Ca^2+PO_4^3-

相关内容