Chemfig documentation has an example, in French, about making a customized lewis
macro accepting an arbitrary angle in degrees. I am reproducing it irresponsibly translated to English. (I am a native Brazilian Portuguese speaker, so I don't master neither English nor French). This example appeared on page 45 (46th page as there is a cover):
\example*{Pairs at arbitrary angles}|\makeatletter
\newcommand\mylewis[3][2ex]{% #1=distance, #2=atom #3=list of angles
\tikzpicture[baseline,anchor=base]%
\node[inner sep=0pt,outer sep=1pt,circle,overlay](atom@@)at(0,0){\phantom{#2}};%
\node[inner sep=0pt,outer sep=0pt]at(0,0){#2};%
\def\list@angle{#3,}%
\loop
\expandafter\grab@angle\list@angle\@nil
\pgfextractx\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimax{\the\CF@dim}%
\pgfextracty\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimay{\the\CF@dim}%
\pgfmathparse{#1*sin(\current@angle)/2}\let\offset@xx\pgfmathresult
\pgfmathparse{#1*cos(\current@angle)/2}\let\offset@yy\pgfmathresult
\draw[line width=.4pt,overlay]
(\CF@dimax-\offset@xx,\CF@dimay+\offset@yy)--(\CF@dimax+\offset@xx,\CF@dimay-\offset@yy);%
\unless\ifx\@empty\list@angle
\repeat
\endtikzpicture
}
\def\grab@angle#1,#2\@nil{\def\current@angle{#1}\def\list@angle{#2}}
\makeatother
Once defined, this macro can be used like this:
\mylewis{Cl}{15}\qquad \mylewis[3ex]{Cl}{-60}\qquad \mylewis[1.5ex]{Cl}{60,120,240,300}
In response to comment asking for dots instead of lines
One attempt to provide both mylewis
and myLewis
:
\makeatletter
\newcommand\mylewis[3][2ex]{% #1=distance, #2=atom #3=list of angles
\tikzpicture[baseline,anchor=base]%
\node[inner sep=0pt,outer sep=1pt,circle,overlay](atom@@)at(0,0){\phantom{#2}};%
\node[inner sep=0pt,outer sep=0pt]at(0,0){#2};%
\def\list@angle{#3,}%
\loop
\expandafter\grab@angle\list@angle\@nil
\pgfextractx\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimax{\the\CF@dim}%
\pgfextracty\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimay{\the\CF@dim}%
\pgfmathparse{#1*sin(\current@angle)/2}\let\offset@xx\pgfmathresult
\pgfmathparse{#1*cos(\current@angle)/2}\let\offset@yy\pgfmathresult
\draw[line width=.4pt,overlay]
(\CF@dimax-\offset@xx,\CF@dimay+\offset@yy)--(\CF@dimax+\offset@xx,\CF@dimay-\offset@yy);%
\unless\ifx\@empty\list@angle
\repeat
\endtikzpicture
}
\newcommand\myLewis[3][2ex]{% #1=distance, #2=atom #3=list of angles
\tikzpicture[baseline,anchor=base]%
\node[inner sep=0pt,outer sep=1pt,circle,overlay](atom@@)at(0,0){\phantom{#2}};%
\node[inner sep=0pt,outer sep=0pt]at(0,0){#2};%
\def\list@angle{#3,}%
\loop
\expandafter\grab@angle\list@angle\@nil
\pgfextractx\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimax{\the\CF@dim}%
\pgfextracty\CF@dim{\pgfpointanchor{atom@@}\current@angle}\edef\CF@dimay{\the\CF@dim}%
\pgfmathparse{#1*sin(\current@angle)/2}\let\offset@xx\pgfmathresult
\pgfmathparse{#1*cos(\current@angle)/2}\let\offset@yy\pgfmathresult
\draw[fill,black]
(\CF@dimax-\offset@xx,\CF@dimay+\offset@yy)circle(0.15ex)%
(\CF@dimax+\offset@xx,\CF@dimay-\offset@yy)circle(0.15ex);%
\unless\ifx\@empty\list@angle
\repeat
\endtikzpicture
}
\def\grab@angle#1,#2\@nil{\def\current@angle{#1}\def\list@angle{#2}}
\makeatother
This way, you can use mylewis
as before, but you now have also myLewis
which appears to be what you really needed.
\mylewis{Cl}{15}\qquad \mylewis[3ex]{Cl}{-60}\qquad \mylewis[1.5ex]{Cl}{60,120,240,300}
\myLewis{Cl}{15}\qquad \myLewis[3ex]{Cl}{-60}\qquad \myLewis[1.5ex]{Cl}{60,120,240,300}
\myLewis[.8ex]{Cl}{15}\qquad \myLewis[.8ex]{Cl}{-60}\qquad \myLewis[.8ex]{Cl}{60,120,240,300}
Please note that I have not delved into much detail over chemfig original Lewis
implementation, so I have only made myLewis
based on the provided mylewis
example. Their difference is simply a change making the end points of the line become the center of little circles.