我想绘制一些盐的示意图,用于教学目的。该图显示了一个可以使用下面的 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Å
和5Å
随后被翻译成12cm
和5cm
。Å
来自埃,你可能已经猜到了。要调整电子的大小,请传入er=.2
选项。
由于我添加了一个可选参数\salt
,因此您可以传递任何 Ti钾Z 样式。如上所示,它可以是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-