使用包中的命令-
,可以自动计算原子间距离并绘制原子之间的链接。但原子间距离设置为原子中间的距离;因此,如果某些原子比其他原子窄,则它们之间的链接更长。如下图所示,之间的链接比更长,因为原子比更窄。\chemfig
chemfig
I-I
Cl-Cl
I
Cl
具体问题是:
我如何才能将原子之间的链接长度设置为一个精确的值,以使不同的原子之间没有差异?
例如,我想将I-I
和之间的链接设置Cl-Cl
为1cm
。这样所有原子都应该可以用一只眼睛看到。
当然需要提到的是,我尝试使用\setatomsep
该包的命令,但是它不能解决我的问题。
\documentclass{article}
\usepackage{chemfig}
\begin{document}
\chemfig{I-I}
\chemfig{Cl-Cl}
\end{document}
给出
答案1
编辑:问题修改后,有了新的答案。
这是一个示例解决方案。思路很明确:让所有原子都具有相同的长度。宽度的位置Mn
可能有一些固定的长度,在我们的小示例中,长度Cl
就足够了。更改\setatomsep
为合适的值就留给你了。
\documentclass{article}
\usepackage{chemfig}
\begin{document}
\chemfig{I-I}
\chemfig{Cl-Cl}
\bigskip
Fixed length:
\bigskip
\newlength{\atomw}
\settowidth{\atomw}{Cl} % Probably the longest name is Mn
\def\MN#1{\makebox[\atomw]{#1}}
\chemfig{\MN{I}-\MN{I}}
\chemfig{\MN{Cl}-\MN{Cl}}
or
\settowidth{\atomw}{Mn} % Probably the longest name is Mn
\chemfig{\MN{I}-\MN{I}}
\chemfig{\MN{Cl}-\MN{Cl}}
\end{document}
答案2
我联系了 Tellechea 先生(chemfig
该软件包的维护者),他回答了我的问题。
我把他的代码放在这里:
\documentclass[11pt]{article}
\usepackage{chemfig}
\makeatletter
\catcode`\~12
\def\CF@chemfig@v{%
\let\CF@next@action\CF@chemfig@v% \`a priori, on reboucle
\ifx\CF@remain@molecule\@empty
\let\CF@next@action\endgroup
\else
\CF@seek@submol
\expandafter\CF@seek@node\expandafter{\CF@remain@molecule}\CF@current@atomgroup\CF@remain@molecule
\ifx\@empty\CF@current@atomgroup% pas de noeud pour commencer ?
\def\CF@bond@outnode{n\CF@last@groupnumber-%
\ifx\CF@current@fromatom\@empty
\ifdim\CF@current@angle pt<90pt \number\CF@cnt@atomingroup
\else\ifdim\CF@current@angle pt>270pt \number\CF@cnt@atomingroup\else1\fi
\fi
\else\CF@current@fromatom
\fi}%
\expandafter\futurelet\expandafter\CF@toks@a\expandafter\CF@gobble@tonil\CF@remain@molecule\relax\@nil
\CF@if@firsttokin@i{-=<>~}% la suite est une liaison
{\ifnum\CF@last@action=\tw@% c'est la deuxi\`eme liaison cons\'ecutive ?
\CF@insert@emptygroup\CF@remain@molecule% ins\`ere un groupe vide
\edef\CF@bond@outnode{\CF@bond@outnode}%
\else
\ifCF@incycle\advance\CF@cnt@cycle\@ne\fi
\expandafter\CF@analyse@bond\expandafter{\CF@remain@molecule}\CF@bond@type
\edef\CF@bond@outnode{\CF@bond@outnode}%
\let\CF@remain@molecule\CF@remain@afterbond
\ifCF@incycle
\ifnum\CF@cnt@cycle=\CF@cycle@num\relax
\expandafter\expandafter\expandafter\@firstoftwo
\else
\expandafter\expandafter\expandafter\@secondoftwo
\fi
\else
\expandafter\@secondoftwo
\fi
{\let\CF@next@action\endgroup
\CF@draw@bond\CF@bond@type{\CF@bond@outnode}{\CF@hook@cycle}\CF@previous@atomgroup\CF@hook@atomgroup
}%
{\node[at=(\CF@bond@outnode\unless\ifCF@incycle.\CF@current@angle\fi),shift=(\ifcase\CF@split@state\or180-\or-\fi\CF@current@angle:\CF@current@length*\CF@atom@sep)](CF@node){};
\let\CF@previous@angle\CF@current@angle
\let\CF@last@action\tw@
}%
\fi
\ifcat\relax\detokenize\expandafter{\romannumeral-`\.\expandafter\noexpand\CF@remain@molecule}\relax
% s'il ne reste plus rien apr\`es la liaison (sans tenir compte de l'espace devant)-> ins\`ere un groupe vide
\CF@insert@emptygroup\CF@remain@molecule
\fi
}%
{\edef\CF@bond@outnode{\CF@bond@outnode}% \'evalue le l'atome de d\'epart de liaison
\ifx(\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi% une parenth\`ese pour commencer ?
{\ifnum\CF@last@action=\tw@% il y avait une liaison juste avant ?
\CF@insert@emptygroup\CF@remain@molecule
\else
\expandafter\CF@grab@submol\expandafter{\CF@remain@molecule}%
\begingroup
\ifCF@incycle\let\CF@last@action\thr@@\fi% on \'etait dans un cycle
\CF@incyclefalse
\aftergroup\CF@chemfig@v
\def\CF@next@action{\expandafter\CF@chemfig@iv\expandafter{\CF@sub@mol}}%
\fi
}%
{\ifx\CF@remain@molecule\@empty
\let\CF@next@action\endgroup
\else% ce qui reste apr\`es le noeud courant n'est pas vide, ne commence pas par "-=~", ni par une parenth\`ese
\ifx*\CF@toks@a\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi% un cycle ?
{\ifnum\CF@last@action=\tw@
\CF@insert@emptygroup\CF@remain@molecule% ins\`ere un groupe vide
\else
\ifCF@incycle\let\CF@last@action\thr@@\fi% on \'etait dans un cycle
\ifnum\CF@last@action=\thr@@\let\CF@lastcycle@num\CF@cycle@num\fi
\CF@expafterarg@ntimes2\CF@if@firsttokmatch{\expandafter\@gobble\CF@remain@molecule}*% un 2\`e "*" ?
{\CF@expafterarg@ntimes2{\def\CF@remain@molecule}{\expandafter\@gobble\CF@remain@molecule}% enl\`eve la 1er \'etoile
\CF@expafterarg@ntimes2\CF@if@firsttokmatch{\expandafter\@gobble\CF@remain@molecule}[% un crochet ensuite ?
{\expandafter\CF@cycle@parsepreamblewithoptarg\CF@remain@molecule\@nil% \begingroup inclus
}%
{\def\CF@cyclearc@startangle{0}\def\CF@cyclearc@endangle{360}%
\let\CF@cyclearc@directtikz\@empty
\expandafter\CF@cycle@parsepreamble\CF@remain@molecule\@nil% \begingroup inclus
}%
\CF@cyclearctrue
}%
{\expandafter\CF@cycle@parsepreamble\CF@remain@molecule\@nil% \begingroup inclus
\CF@cyclearcfalse
}%
\CF@cnt@cycle\z@
\edef\CF@hook@cycle{\CF@bond@outnode}%
\let\CF@hook@atomgroup\CF@previous@atomgroup
\CF@incycletrue
\ifnum\CF@last@action=\thr@@
\pgfmathparse{360/\CF@lastcycle@num-180}% c'est un cycle dans un cycle
\else
\pgfmathparse{-180/\CF@cycle@num-90+\CF@cycle@anglecorrection}%
\fi
\let\CF@initcycle@angle\pgfmathresult
\aftergroup\CF@chemfig@v
\def\CF@next@action{\expandafter\CF@chemfig@iv\expandafter{\CF@sub@mol}}%
\fi
}%
{\errmessage{Package \CF@package@name\space Error: something went wrong here: \detokenize\expandafter{\CF@remain@molecule}^^JIf you think it's a bug, please, send a Minimal Example to the author.}}%
\fi}%
}%
\else
\CF@expand@second{\CF@expand@second{\CF@expand@second\CF@draw@atomgroup\CF@current@angle}\CF@current@toatom}\CF@current@atomgroup
\fi
\fi
\CF@next@action
}
\def\CF@draw@atomgroup#1#2#3{% #1=angle d'arriv\'ee de la liaison #2=numero atome sur lequel arrive la liaison #3=groupe d'atomes
\expandafter\let\expandafter\CF@bond@outcontent% assigne le contenu de l'atome d'o\`u part la liaison
\csname
\ifdefined\CF@bond@outnode
atom@\expandafter\CF@extract@atom\CF@bond@outnode\@nil
\else
@empty%
\fi
\endcsname
\global\advance\CF@cnt@groupnumber\@ne
\let\CF@current@atom\@empty
\global\let\CF@hook@drawlist\@empty
\CF@cnt@atomingroup\z@
\CF@if@firsttokmatch{#3}?{\CF@draw@atomgroup@i{{}#3}}{\CF@draw@atomgroup@i{#3}}%
\def\CF@current@atomgroup{#3}%
\CF@remove@movearg\CF@current@atomgroup% enl\`eve les "@{<nom>}"
\CF@if@instr{#3}?%
{\CF@remove@hook\CF@current@atomgroup
\ifcat\relax\detokenize\expandafter{\romannumeral-`\.\expandafter\noexpand\CF@current@atomgroup}\relax
\let\CF@current@atomgroup\CF@empty@node
\fi
}%
\relax
\ifx\@empty#2\@empty
\else
\ifnum#2<\@ne
\immediate\write\CF@unused{Package \CF@package@name\space Warning: no atom found at position #2, pershaps you mispelled the optional argument of the bond.}%
\else
\ifnum#2>\CF@cnt@atomingroup
\errmessage{Package \CF@package@name\space Error: no atom found at position #2, pershaps you mispelled the optional argument of the bond.}%
\fi
\fi
\fi
\edef\CF@hook@atomnumber{%
\ifx\@empty#2\@empty
\ifdim#1pt>90pt
\ifdim#1pt<270pt \number\CF@cnt@atomingroup\else1\fi
\else1%
\fi
\else#2%
\fi}%
\CF@cnt@atomnumber\CF@hook@atomnumber
\ifx\CF@current@atomgroup\CF@empty@node
\let\CF@node@strut\@empty
\else
\ifx\@empty\CF@bond@outcontentsaved
\def\CF@node@strut{\vphantom\CF@bond@outcontent}%
\else
\def\CF@node@strut{\vphantom\CF@bond@outcontentsaved}%
\fi
\fi
\edef\CF@opt@string{anchor=\ifnum\CF@last@action=\z@ base\else\ifCF@incycle center\else180+#1\fi\fi,at=(CF@node),\CF@node@style}% premier atome de la mol\'ecule affich\'e
\loop
\unless\ifnum\CF@cnt@atomnumber>\CF@cnt@atomingroup
\expandafter\expandafter\expandafter\futurelet\expandafter\expandafter\expandafter\CF@toks@a\expandafter\expandafter\expandafter
\CF@gobble@tonil\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil
\expandafter\ifx\string @\CF@toks@a% l'atome courant commence par un "@"
\expandafter\expandafter\expandafter\CF@gobble@movearg\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil\CF@moveatom@name
\expandafter\node\expandafter[\CF@opt@string,overlay](\CF@moveatom@name){\phantom{\CF@node@content}};%
\let\CF@moveatom@name\@empty
\fi
\expandafter\node\expandafter[\CF@opt@string](n\number\CF@cnt@groupnumber-\number\CF@cnt@atomnumber){\CF@node@content};%
\let\CF@node@strut\@empty
\advance\CF@cnt@atomnumber\@ne
\edef\CF@opt@string{anchor=base \ifnum\CF@split@state=\@ne east\else west\fi,at=(n\number\CF@cnt@groupnumber-\number\numexpr\CF@[email protected] \ifnum\CF@split@state=\@ne west\else east\fi),\CF@node@style}%
\repeat
\CF@cnt@atomnumber\CF@hook@atomnumber
\ifnum\CF@last@action=\tw@% s'il faut tracer une liaison
\gdef\CF@cycle@anglecorrection{0}% alors c'est qu'un cycle ne peut pas commencer la mol\'ecule : annulation de la correction d'angle
\CF@draw@bond\CF@bond@type{\CF@bond@outnode}{n\number\CF@cnt@groupnumber-\number\CF@cnt@atomnumber}\CF@previous@atomgroup\CF@current@atomgroup
\fi
\let\CF@last@action\@ne% met la derni\`ere action \`a 1 : affichage d'un noeud
\loop
\ifnum\CF@cnt@atomnumber>\@ne
\advance\CF@cnt@atomnumber\m@ne
\edef\CF@opt@string{anchor=base \ifnum\CF@split@state=\@ne west\else east\fi,at=(n\number\CF@cnt@groupnumber-\number\numexpr\CF@cnt@atomnumber+1.base \ifnum\CF@split@state=\@ne east\else west\fi),\CF@node@style}%
\expandafter\expandafter\expandafter\futurelet\expandafter\expandafter\expandafter\CF@toks@a\expandafter\expandafter\expandafter
\CF@gobble@tonil\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil
\expandafter\ifx\string @\CF@toks@a% l'atome courant commence par un "@"
\expandafter\expandafter\expandafter\CF@gobble@movearg\csname atom@\number\CF@cnt@atomnumber\endcsname\@nil\CF@moveatom@name
\expandafter\node\expandafter[\CF@opt@string,overlay](\CF@moveatom@name){\phantom{\CF@node@content}};%
\let\CF@moveatom@name\@empty
\fi
\expandafter\node\expandafter[\CF@opt@string](n\number\CF@cnt@groupnumber-\number\CF@cnt@atomnumber){\CF@node@content};%
\repeat
\CF@hook@drawall
\edef\CF@last@groupnumber{\number\CF@cnt@groupnumber}%
\let\CF@previous@atomgroup\CF@current@atomgroup
}
\catcode`\~13
\makeatother
\begin{document}
\baselineskip=8mm
\chemfig{I-I}
\chemfig{Cl-Cl}
\chemfig{C=O}
\chemfig{N~C}
\chemfig{Abcedefgh-Abcdefgh-[6]Ijkl-Mnopq}
\chemfig{A*6(-Bc-Def-\lewis{1:,G}-H-I-)}
\end{document}
结果: