# Draw a Frost circle in Latex

In chemistry, a Frost circle is a quick method to estimate the relative energy levels of the pi molecular orbitals in a cyclic compound and then based on electron placement judge its aromaticicity. I'm looking for a way to create these in LaTeX, preferably using the functionality of packages like chemfig and tikzorbital, but I will settle for a tikz only solution.

A Frost circle is created by inscribing the polygon for the cyclic compound (for example a regular hexagon for benzene) inside a circle with one vertex of the polygon oriented downward. Each location where a vertex of the polygon touches the circle, this is a molecular orbital that can have up to two electrons in it (represented by fishhook arrows). The orbitals below the horizontal line that bisects the circle are bonding orbitals. Those above are antibonding orbitals. Any orbitals on that lay on the line are nonbonding orbitals. Electrons are placed into the orbitals by some rules.

• The aufbau principle: Orbitals are filled in order of increasing energy.
• The Pauli exclusion principle: Each orbital can hold only two electrons and their spins (arrow directions) must be opposite.
• Hund's rule: If two orbitals have the same energy, one electron does into each before either gets its second electron.

Here is a longer description of the method and its application.

My ideal solution is new command that takes the ring size and number of electrons as an input and builds Frost circles like the following examples by:

• Drawing the circle
• Inscribing the regular polygon with number of sides equal to ring size (up to 10)
• Drawing horizontal line segments at the vertices of the polygon for the molecular orbitals
• Drawing the vertical energy axis
• Drawing the dashed line for the bonding/antibonding division
• Populating the number of electrons by the rules above

Here are some examples: benzene (ring size = 6, electrons = 6)

cyclopentadienyl cation (ring size = 5, electrons = 4)

cyclooctatetraene (ring size = 8, electrons = 8)

• Excuse me very much for this comment. But do you have seen these images? – Sebastiano Oct 8 '20 at 15:12
• @Sebastiano - I made these images in chemistry drawing software, but each one took about 10 minutes. Because they contain a mixture of chemical structure and nonstructural elements, I cannot export them as vector graphics. If I could do that, I would just import them into my latex document that way. I am working on a document where I may want to draw dozens of these. – Ben Norris Oct 8 '20 at 16:10
• The images are crisp and clear even without svg format, you can just store png images to a large enough scale so that when they are zoomed-out when included in the PDF, they become even smoother. – AboAmmar Oct 8 '20 at 16:32
• @AboAmmar - I understand that, but the time commitment for making one is large for very repetitive work. I would like to have a macro that automates it since I plan to make dozens of these. – Ben Norris Oct 8 '20 at 16:34
• @BenNorris You could to draw your images using Mathcha editor. mathcha.io/editor – Sebastiano Oct 8 '20 at 17:09

Here is a fully automated solution. The calls for your three examples are

\frost{6}{6}
\frost{5}{4}
\frost{8}{8}


There is an optional argument for radius size. Default is 1cm. So frost[2cm]{6}{6} would have a radius of 2cm.

Note: This only works (at the moment) if there are an even number of electrons.

\documentclass{article}

\usepackage{tikz}
\usepackage{ifthen}

\usetikzlibrary{decorations.markings}
\tikzset% Define decorations
{updown/.style={postaction=decorate, decoration={markings, mark=at position .5 with
{\draw[line join=round] (-2pt,-\arrlen)--++(0pt,2*\arrlen)--(-4pt,1pt);
\draw[line join=round] (2pt,\arrlen)--++(0pt,-2*\arrlen)--(4pt,-1pt);
}}},% 2 arrows
uparr/.style={postaction=decorate, decoration={markings, mark=at position .5 with
{\draw[line join=round] (0pt,-\arrlen)--++(0pt,2*\arrlen)--(-2pt,1pt);
}}},% 1 arrow, right side
dnarr/.style={postaction=decorate, decoration={markings, mark=at position .5 with
{\draw[line join=round] (0pt,\arrlen)--++(0pt,-2*\arrlen)--(2pt,-1pt);
}}}% 1 arrow left side (points down since lines will be drawn right to left)
}

\newcommand{\orblen}{.8}% length of horizontal segments as a percentage of main radius
\newcommand{\arrlen}{.25cm}% half length of each arrow

\newcommand{\frost}[3][1cm]% optional argument is circle radius, #2=edges, #3=electrons
{\begin{tikzpicture}[line width=1pt]
\ifthenelse{#3 = 0}{\draw(-.5*#1*\orblen,-#1)--(.5*#1*\orblen,-#1);}% draw bottom line segment...
{\draw[updown](-.5*#1*\orblen,-#1)--(.5*#1*\orblen,-#1);}% ...with arrows if >0 electrons
\foreach \k [evaluate=\k as \r using .5*#2+1,% point right if k<r, point left if k>r, top if k=r
evaluate=\k as \t using (\k-1)*360/#2-90,% angles of polygon vertices. k=1 is bottom.
evaluate=\k as \n using -4*\k+6+#3,% who gets 2 electrons (right)?
evaluate=\k as \m using -4*(#2+2-\k)+6+#3,% who gets 2 electrons (left)?
evaluate=\k as \j using 2*#2] in {1,...,#2}% electrons for top if #3=2*#2
{\draw(\t:#1)--(\t+360/#2:#1);
{\ifthenelse{\lengthtest{\k pt < \r pt}}% right side
{\ifthenelse{3 < \n}{\draw[updown](\t:#1)--+(#1*\orblen,0);}% 2 arrows
{\ifthenelse{1 < \n}{\draw[uparr](\t:#1)--+(#1*\orblen,0);}% 1 arrow
{\draw(\t:#1)--+(#1*\orblen,0);}}}% no arrows
{\ifthenelse{\lengthtest{\k pt > \r pt}}% left side
{\ifthenelse{3 < \m}{\draw[updown](\t:#1)--+(-#1*\orblen,0);}% 2arrows
{\ifthenelse{1 < \m}{\draw[dnarr](\t:#1)--+(-#1*\orblen,0);}% 1 arrow
{\draw(\t:#1)--+(-#1*\orblen,0);}}}%no arrows
{\ifthenelse{#3 = \j}{\draw[updown](-.5*#1*\orblen,#1)--(.5*#1*\orblen,#1);}% 2 arrows on top
{\draw(-.5*#1*\orblen,#1)--(.5*#1*\orblen,#1);}}} % no arrows on top
}{} % do nothing if k=1 (bottom)
}
\draw[dotted](-2*#1,0)--(3*#1,0)node[below]{bonding\phantom{anti}}node[above]{antibonding};
\draw[-latex](-2.2*#1,-#1)--node[sloped,above,pos=.4]{Energy}(-2.2*#1,1.8*#1);
\end{tikzpicture}
}

\begin{document}

\frost{6}{6}

\frost{5}{4}

\frost{8}{8}

\end{document}

• Very good also your answer. – Sebastiano Oct 9 '20 at 22:02
• Excellent! This works beautifully. – Ben Norris Oct 10 '20 at 20:27

Honestly, it's taken some effort, but your figure was intriguing and it allowed me to learn new things1 so, it's all good.

Basically I've created a \newcommand, name \Frostcircle, which has 2 arguments, options and the electrons.

Currently, the [options] are:

• radius = the radius of the circle, please note that at the moment the surrounding graphics do not adjust if you make it too big. I might work on it in the future. It only takes a number (in cm) at the moment, using lengths breaks it, I'm not sure why yet. Suggestions are welcome.
• ring size = this refers to the number of sides of the polygon. Number of sides from 5 to 10 have been tested. As you might expect, it takes a number as argument
• frost label = this is the label at the top, default is empty. Make sure to surround the text with curly braces, e.g. frost label={My label here}

The other argument are the electrons, the easiest way I could find is to set them in a counterclockwise fashion, starting from the top, as in this figure:

It takes values 0, 1, and 2: in order, no electron, one electron, two electrons. You can supply it as a list so giving {0,0,2,2,2,0} would give your benzene frost circle. It might sound counterintuitive but it's actually simple once you give it a try.

If the number of elements in the list you provide are less than the ring size, you will get an error and the code will not compile. If you want no electron, just type 0 to solve this.

### Notes

The direction of the "arrow" for the electron is inverted on the other side, not sure if this is important for your graphs. I can look into it another day if it's important. FIXED

Also I added the same packages as in Sebastiano's answer to get the math font, but they are not needed for the command to work.

## Code

\documentclass[margin=10pt]{article}
\usepackage{tikz}
\usepackage{newtxtext}
\usepackage{amssymb}
\usepackage{bm}

\usetikzlibrary{arrows.meta,decorations.markings,shapes.geometric}

\tikzset{%
electron/.style={%
postaction={decorate,
decoration={%
markings,
mark=at position .5 with
{%
\ifnum#1=1\relax%
\draw[-{Straight Barb[left,angle=60:2pt 3]}] (0,-6pt) --(0,6pt);
\else
\ifnum#1=2\relax%
\draw[-{Straight Barb[left,angle=60:2pt 3]}] (-1pt,-6pt) -- (-1pt,6pt);
\draw[{Straight Barb[left,angle=60:2pt 3]}-] (1pt,-6pt) -- (1pt,6pt);
\else
\fi\fi
}}
}
},
mlbl/.style={anchor=south, align=center, midway, sloped},
}

\pgfkeys{/tikz/.cd,% to set the path
ring size/.initial=5,
ring size/.get=\numbersides,
ring size/.store in=\numbersides,
frost label/.initial=,
frost label/.get=\frostlabel,
frost label/.store in=\frostlabel,
}

\newcommand\Frostcircle[2][]{%
\begin{tikzpicture}[line width=1pt]
\draw[-{Stealth[scale=1.5]}] (0,0) -- (0,3cm)
node[mlbl] {Energy}
node[anchor=north west, xshift=2mm] {\frostlabel};
\draw[dotted, shorten >=-1cm] (.5,1) -- (4,1)
node[anchor=south west] {antibonding}
node[anchor=north west] {bonding};
\node[%
regular polygon,
rotate=360/\numbersides/2,
regular polygon sides=\numbersides,
draw,
outer sep=0pt
] at (2,1) (FrostCircle) {};

\def\electronarrow{{#2}}
\foreach \polycorner [count=\findex starting from 0] in {1,...,\numbersides}{%
\pgfmathtruncatemacro\maximumhalf{\numbersides/2+1}
\pgfmathsetmacro\Findex{\electronarrow[\findex]}
\ifnum\polycorner=1\relax%
\draw[electron=\Findex] (FrostCircle.corner \polycorner)++(-.8,0) --++ (1.6,0);
\else
\ifnum\polycorner=\maximumhalf\relax%
\draw[electron=\Findex] (FrostCircle.corner \polycorner)++(-.8,0) --++ (1.6,0);
\else
\ifnum\polycorner<\maximumhalf\relax%
\draw[electron=\Findex] (FrostCircle.corner \polycorner)++ (-.8,0) -- (FrostCircle.corner \polycorner);
\else
\draw[electron=\Findex] (FrostCircle.corner \polycorner) --++ (.8,0);
\fi\fi\fi
}%
\end{tikzpicture}%
}

\begin{document}

\Frostcircle[%
ring size=6,
frost label={benzene (ring size = 6, electrons = 6)}
]{0,0,2,2,2,0}

\vspace{1cm}

\Frostcircle[%
ring size=5,
frost label={cyclopentadienyl cation (ring size = 5, electrons = 4)}
]{0,1,2,1,0}

\vspace{1cm}

\Frostcircle[%
ring size=8,
frost label={cyclooctatetraene (ring size = 8, electrons = 8)}
]{0,0,1,2,2,2,1,0}

\end{document}


1: The pgfkeys.

• Thank you very much for the citation of my name :-) ; for my humble opinion it not was important. Your different codes are perfect!!!! +1 – Sebastiano Oct 9 '20 at 19:48
• This is great! Generally in the ground state, unpaired electrons (arrows) would have the same spin (same direction), so SandyG's solution matches my needs a little better. – Ben Norris Oct 10 '20 at 20:32
• @BenNorris interesting. I'll take a look at that later. It shouldn't be hard to achieve. – Alenanno Oct 10 '20 at 20:35
• @BenNorris I just wanted to let you know, I fixed the direction. It was rather easy, not sure why I didn't think of it sooner. – Alenanno Oct 10 '20 at 21:19

I have done with Mathcha the first example. For my humble opinion it seem very similar...but there is a latin maxime: "de gustibus non disputandum est".

\documentclass[a4paper,12pt]{article}
\usepackage{tikz}
\usepackage{newtxtext}
\usepackage{amssymb}
\usepackage{bm}

\begin{document}

\tikzset{every picture/.style={line width=0.75pt}} %set default line width to 0.75pt

\begin{tikzpicture}[x=0.75pt,y=0.75pt,yscale=-1,xscale=1]
%uncomment if require: \path (0,300); %set diagram left start at 0, and has height of 300

%Shape: Regular Polygon [id:dp9024119328579219]
\draw  [line width=1.5]  (203,184) -- (161.86,160.25) -- (161.86,112.75) -- (203,89) -- (244.14,112.75) -- (244.14,160.25) -- cycle ;
%Shape: Circle [id:dp3742321630799761]
\draw  [line width=1.5]  (155.5,136.5) .. controls (155.5,110.27) and (176.77,89) .. (203,89) .. controls (229.23,89) and (250.5,110.27) .. (250.5,136.5) .. controls (250.5,162.73) and (229.23,184) .. (203,184) .. controls (176.77,184) and (155.5,162.73) .. (155.5,136.5) -- cycle ;
%Straight Lines [id:da6431705906977057]
\draw [line width=1.5]    (101,185) -- (101,31.71) ;
\draw [shift={(101,27.71)}, rotate = 450] [fill={rgb, 255:red, 0; green, 0; blue, 0 }  ][line width=0.08]  [draw opacity=0] (13.4,-6.43) -- (0,0) -- (13.4,6.44) -- (8.9,0) -- cycle    ;
%Straight Lines [id:da03628267423150655]
\draw [line width=1.5]    (176.75,89) -- (229.25,89) ;
%Straight Lines [id:da6999074691962319]
\draw [line width=1.5]    (244.14,112.75) -- (285.5,112.75) ;
%Straight Lines [id:da6267867712352968]
\draw [line width=1.5]    (120.5,112.75) -- (161.86,112.75) ;
%Straight Lines [id:da4603867099439829]
\draw [line width=1.5]    (244.14,160.25) -- (285.5,160.25) ;
%Straight Lines [id:da018369347304083128]
\draw [line width=1.5]    (120.5,160.25) -- (161.86,160.25) ;
%Straight Lines [id:da7545009709936943]
\draw [line width=1.5]    (176.75,184) -- (229.25,184) ;
%Straight Lines [id:da42526907269791137]
\draw [line width=1.5]  [dash pattern={on 1.69pt off 2.76pt}]  (120.5,136.5) -- (346.5,136.5) ;

% Text Node
\draw (126,149.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\upharpoonleft }$};
% Text Node
\draw (249,149.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\upharpoonleft }$};
% Text Node
\draw (195,173.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\upharpoonleft }$};
% Text Node
\draw (130,149.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\downharpoonright }$};
% Text Node
\draw (253,149.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\downharpoonright }$};
% Text Node
\draw (200,173.4) node [anchor=north west][inner sep=0.75pt]  [font=\large]  {$\bm{\downharpoonright }$};
% Text Node
\draw (74,149) node [anchor=north west][inner sep=0.75pt]  [font=\large,rotate=-270] [align=left] {Energy};
% Text Node
\draw (288,103) node [anchor=north west][inner sep=0.75pt]  [font=\large] [align=left] {Antibonding};
% Text Node
\draw (288,150) node [anchor=north west][inner sep=0.75pt]  [font=\large] [align=left] {Bonding};
% Text Node
\draw (120,36) node [anchor=north west][inner sep=0.75pt]   [align=left] {\large benzene (6 atoms, 6 electrons)};

\end{tikzpicture}
\end{document}