如何在 chemfig 包中设置固定的原子间距离?

如何在 chemfig 包中设置固定的原子间距离?

使用包中的命令-,可以自动计算原子间距离并绘制原子之间的链接。但原子间距离设置为原子中间的距离;因此,如果某些原子比其他原子窄,则它们之间的链接更长。如下图所示,之间的链接比更长,因为原子比更窄。\chemfigchemfigI-ICl-ClICl

具体问题是:

我如何才能将原子之间的链接长度设置为一个精确的值,以使不同的原子之间没有差异?

例如,我想将I-I和之间的链接设置Cl-Cl1cm。这样所有原子都应该可以用一只眼睛看到。

当然需要提到的是,我尝试使用\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}

结果:

在此处输入图片描述

相关内容