(7) 重合体

2017-10-02 2025-02-10

本稿は chemfig v1.66 をもとにしています。

基本形

chemfig で重合体を描いてみましょう。 といっても、最新の chemfig ではかなり楽に描けるようになっています。

それはそれとして、まずは chemfig のマニュアル通りに描いてみます。

\chemfig{\vphantom{CH_2}-[@{op,.75}]CH_2-CH_2-[@{cl,.25}]}
\polymerdelim[height = 5pt, indice = \!\!n]{op}{cl}

このようにすると、

となります。

-[@{op,.75}] の部分は 単結合 - の 0.75 の位置 (始点 を 0、終点 を 1 とする) に op という名前 (ラベル) を付ける、の意味です。 \polymerdelim で開き括弧・閉じ括弧をそれぞれ (すでに \chemfig{} 内で定義した) op, cl の位置に描いています。 なお \! は負のスペースです。

括弧の位置などはかなり柔軟に指定できるようになっており、多くの場合は標準の機能だけで十分でしょう。 詳細はマニュアルを参照して下さい。

高さの自動調整 (1)

ただし標準の方法では自分で高さ・深さを指定しなければなりません。 これを分子の高さ(や深さ)に自動的に合わせたい、という場合もあるかもしれません。 その場合は以下のようなコードで実現できます ( chemfig\polymerdelim をちょこっと変えただけです)。

\catcode`\_=11
\def\polymerfulldelim{\CF_ifnextchar[{\CF_polymerfulldelima}{\CF_polymerfulldelima[]}}
\def\CF_polymerfulldelima[#1]#2#3#4{%
  \restoreKV[CFdelimiters]%
  \CF_doifnotempty{#1}{\setKV[CFdelimiters]{#1}}%
  \settoheight{\CF_dim}{#4}\edef\CF_delimheight{\the\CF_dim}%
  \settodepth{\CF_dim}{#4}\edef\CF_delimdepth{\the\CF_dim}%
  \edef\CF_delimhalfdim{\the\dimexpr(\CF_delimheight+\CF_delimdepth)/2}%
  \edef\CF_delimvshift{\the\dimexpr(\CF_delimheight-\CF_delimdepth)/2}%
  #4%
  \chemmove{%
    \nulldelimiterspace0pt
    \pgfextractx\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimx{\the\CF_dim}%
    \pgfextractx\CF_dim{\pgfpointanchor{#3}{center}}\edef\CF_rightdelimx{\the\CF_dim}%
    \node[at={(\CF_leftdelimx+\CF_leftdelimxshift,\CF_delimvshift)}]
    {$\left\CF_leftdelim\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right.$};%
    \node[at={(\CF_rightdelimx+\CF_rightdelimxshift,\CF_delimvshift)}]
    {$\left.\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right\CF_rightdelim
      \CF_eexpsecond\CF_doifnotempty{\useKV[CFdelimiters]{indice}}
      {\CF_underscore{\rlap{$\scriptstyle\useKV[CFdelimiters]{indice}$}}}
      $};
  }}
\catcode`\_=8

コマンド名がちょっとあれですが、そこは気にしないでいただけると有り難いです。

この \polymerfulldelim は、

\polymerfulldelim[k=v,k=v,...]{ノード1}{ノード2}{分子}

のように使います。 [, ] 内では \polymerdelim と同様に、 delimiters, open xshift, close xshift, indice が指定できます。 元の \polymerdelim とは異なり、このコマンド内で {分子} を描画するので、事前にこの分子を書いておく必要はありません。

例えば PET の場合は次のようにします。

\polymerfulldelim[delimiters={[]},indice=\!\!n]{op}{cl}{\chemfig{
    Ar-[:30](=[:90]O)-[:-30]O-[:30]-[:-30]-[:30]O
    -[@{op,.5}:-30]
    (=[:-90]O)-[:30]*6(-=-
    (-[:30](=[:90]O)-[:-30]O-[:30]-[:-30]-[:30]O
    -[@{cl,.5}:-30]
    (=[:-90]O)-[:30]Ar)=-=)}}

なおこの方法だと一つの分子 (正確には一つの \chemfig 内) に複数の括弧を描きたいという場合には対応できません。 (レアケースだと思うのでひとまず気にしないことにします。)

高さの自動調整 (2)

上のコマンドでは指定された {分子} 全体の高さ・深さを使用して括弧の高さ・深さを決定するので、括弧内の要素の高さ・深さと一致するとは限りません。 括弧の外に、括弧内より高い・深い部分があると、その部分も含めて括弧の高さ・深さが決まります。

例えば、ナイロン6 は次のようになります。 開き括弧の左にある =O も含めて高さが決められているのが分かります。

\polymerfulldelim[delimiters={[]},indice=\!\!n]{op}{cl}{\chemfig{
    R-[:30](=[:90]O)
    -[@{op}:-30]
    \chembelow{N}{H}
    -[:30]-[:-30]-[:30]-[:-30]-[:30]-[:-30](=[:-90]O)
    -[@{cl}:30]
    \chemabove{N}{H}-[:-30]R
}}

これはこれでアリだとは思いますが、括弧内の部分の高さに合わせて描きたいという場合は、例えば次のようにすることができます。

\catcode`\_=11
\def\polymerdelimsetheight{\CF_ifnextchar[{\CF_polymerdelimsetheighta}{\CF_polymerdelimsetheighta[]}}
\def\CF_polymerdelimsetheighta[#1]#2#3#4{%
  \restoreKV[CFdelimiters]%
  \CF_doifnotempty{#1}{\setKV[CFdelimiters]{#1}}%
  \settoheight{\CF_dim}{#4}\edef\CF_delimheight{\the\CF_dim}%
  \settodepth{\CF_dim}{#4}\edef\CF_delimdepth{\the\CF_dim}%
  \edef\CF_delimhalfdim{\the\dimexpr(\CF_delimheight+\CF_delimdepth)/2}%
  \edef\CF_delimvshift{\the\dimexpr(\CF_delimheight-\CF_delimdepth)/2}%
  \chemmove{%
    \nulldelimiterspace0pt
    \pgfextractx\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimx{\the\CF_dim}%
    \pgfextracty\CF_dim{\pgfpointanchor{#2}{center}}\edef\CF_leftdelimy{\the\CF_dim}%
    \pgfextractx\CF_dim{\pgfpointanchor{#3}{center}}\edef\CF_rightdelimx{\the\CF_dim}%
    \node[at={(\CF_leftdelimx+\CF_leftdelimxshift,\CF_leftdelimy+\CF_delimvshift)}]
    {$\left\CF_leftdelim\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right.$};%
    \node[at={(\CF_rightdelimx+\CF_rightdelimxshift,\CF_leftdelimy+\CF_delimvshift)}]
    {$\left.\vrule height\CF_delimhalfdim depth\CF_delimhalfdim width0pt\right\CF_rightdelim
      \CF_eexpsecond\CF_doifnotempty{\useKV[CFdelimiters]{indice}}
      {\CF_underscore{\rlap{$\scriptstyle\useKV[CFdelimiters]{indice}$}}}
      $};
  }}
\catcode`\_=8
\chemfig{
    R-[:30](=[:90]O)
    -[@{op2}:-30]
    \chembelow{N}{H}
    -[:30]-[:-30]-[:30]-[:-30]-[:30]-[:-30](=[:-90]O)
    -[@{cl2}:30]
    \chemabove{N}{H}-[:-30]R
}
\polymerdelimsetheight[delimiters={[]},indice=\!\!n]{op2}{cl2}{\chemfig{
    -[:-30,0.5]
    \chembelow{N}{H}
    -[:30]-[:-30]-[:30]-[:-30]-[:30]-[:-30](=[:-90]O)
    -[:30,0.5]% こちらの ,0.5 は(この例では)無くても問題ない
}}

少しヤヤこしくて申し訳ありませんが、このコマンドを使うには、まず対象の分子を描き、 \polymerdelimsetheight の最後の引数で括弧内の部分を記述します。 この部分は高さの計算に使うだけなので、高さ・深ささえ一致していれば、元の分子と完全に一致している必要はありません。 例えば上の場合は -[:30]-[:-30]-[:30]-[:-30] はあっても無くても構いません。

ただし、この部分の開始位置 (高さ) は括弧内と合わせる必要があります。 したがってここでは、元の分子に合わせて、最初 (と最後) の結合で長さを指定し -[:-30,0.5] 等としています。 また、 \polymerdelimsetheight の最後の引数では、元の分子での括弧のラベル (ここでは op2, cl2) を使用してはいけません。

ということで、ちょっと使いにくいコマンドになってしまいました。

このようなこともできるという意味で例として挙げておきますが、マニュアル通りの方法を使うのが一番無難だと思います。 また、ここのコードは十分に検証していないので、不具合が発生する場合もあるかもしれません。 使用される場合はその点にご留意下さい。