2

I'm trying to find a simple way to draw this but can't find a solution

enter image description here

5
  • 1
    What is your best solution so far?
    – MS-SPO
    Aug 6, 2021 at 19:50
  • Start with a single ellipse, figure out how to make the changes based on its x,y location, then add a bunch of them. Aug 6, 2021 at 23:35
  • @Diana Where does the figure come from? a book?
    – Black Mild
    Aug 8, 2021 at 16:35
  • yes it is from a textbook
    – Diana
    Aug 9, 2021 at 9:23
  • @Diana What is the name of that textbook?
    – Black Mild
    Aug 9, 2021 at 21:12

2 Answers 2

12

This is a solution following John Kormylo's comment. I use a \foreach command to draw all the ellipses, but I rotate each one and change its minor axis according to its position.

\documentclass[border=2mm]{standalone}
\usepackage{tikz}

\definecolor{positive}{HTML}{FADDB9}
\definecolor{negative}{HTML}{7BC192}

\begin{document}
\begin{tikzpicture}
\foreach\y in {-3,...,3} \foreach\x in {-4,...,4} % row, column
{%
  % atan2 implementation
  \ifnum\x = 0
    \ifnum\y > 0
      \def\a{90}
    \else
      \def\a{-90} 
    \fi
  \else\ifnum\x > 0
    \pgfmathsetmacro\a{atan(\y/\x)}     % angle in quadrants  I and IV
  \else
    \pgfmathsetmacro\a{atan(\y/\x)+180} % angle in quadrants II and III
  \fi\fi
  % dipoles
  \pgfmathtruncatemacro\b{\x*\x+\y*\y}
  \ifnum\b > 0
    \pgfmathsetmacro\bb{0.08*sqrt(\b)} % semi-axis b = distance to the origin (scaled)
    \begin{scope}[shift={(\x,\y)},rotate=\a]
      \fill[positive] (0,\bb) arc (90:-90:0.4 and \bb);
      \fill[negative] (0,\bb) arc (90:270:0.4 and \bb);
      \draw (0,0) ellipse (0.4 and \bb);
      \node[transform shape,scale=0.6] at ( 0.2,0) {$+$};
      \node[transform shape,scale=0.6] at (-0.2,0) {$-$};
    \end{scope}
  \fi
}
% central charge
\draw[fill=red] (0,0) circle (0.15) node[scale=0.6] {$+$} node [red,below left] {$q$};
\end{tikzpicture}
\end{document}

enter image description here Edit: Two changes:

  1. Following Sebastiano's suggestion I adapted the code for positive and negative charges. I added a parameter q that should takes values +1,-1 and that changes accordingly the x-axis. Then I needed an \ifnum for display the central charge.
  2. atan2. Why not use the built-in function? You'll be thinking. Me too...

The new (and shortest) code:

\documentclass[border=2mm]{standalone}
\usepackage{tikz}

\definecolor{positive}{HTML}{FADDB9}
\definecolor{negative}{HTML}{7BC192}

\def\q{-1} % central charge: +1,-1 we only need the sign

\begin{document}
\begin{tikzpicture}
\foreach\y in {-3,...,3} \foreach\x in {-4,...,4} % row, column
{%
  % dipoles
  \pgfmathsetmacro\a{atan2(\y,\x)}
  \pgfmathtruncatemacro\b{\x*\x+\y*\y}
  \ifnum\b > 0
    \pgfmathsetmacro\bb{0.08*sqrt(\b)} % semi-axis b = distance to the origin (scaled)
    \begin{scope}[shift={(\x,\y)},rotate=\a,x=\q cm]
      \fill[positive] (0,\bb) arc (90:-90:0.4 and \bb);
      \fill[negative] (0,\bb) arc (90:270:0.4 and \bb);
      \draw (0,0) ellipse (0.4 and \bb);
      \node[transform shape,scale=0.6] at ( 0.2,0) {$+$};
      \node[transform shape,scale=0.6] at (-0.2,0) {$-$};
    \end{scope}
  \fi
}
% central charge
\draw[fill=red] (0,0) circle (0.15) node [red,below left] {$q$};
\ifnum\q = 1
  \node[scale=0.6] at (0,0) {$+$};
\else
  \node[scale=0.6] at (0,0) {$-$};
\fi
\end{tikzpicture}
\end{document}

And the same picture with a negative central charge: enter image description here

6
  • 1
    Very impressive code and design +1
    – SebGlav
    Aug 7, 2021 at 10:31
  • Thanks, @SebGlav!!! ;-) Aug 7, 2021 at 12:24
  • +1 surely. But if the charge is negative,like is it necessary to change the code? Inverting the plus and minus symbols? \node[transform shape,scale=0.6] at ( 0.2,0) {$+$}; \node[transform shape,scale=0.6] at (-0.2,0) {$-$};?
    – Sebastiano
    Aug 7, 2021 at 22:46
  • 1
    Thanks @Sebastiano!!! Indeed, the code should be changed. I guess it could also be done with \ifnum or \ifthenelse, to take both cases into account but I think it's not worth it. Aug 8, 2021 at 7:24
  • 1
    @Sebastiano, you got me thinking and I made an edit. Now the charge can have both signs. Aug 8, 2021 at 8:26
4

I simplify the code and calculations of @Juan Castano by creating a pic named atom, then putting pics along paths (see option [sloped], no atan2 or angle calculation needed) from the origin to integer points inside a loop.

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\begin{document}
\begin{tikzpicture}
\tikzset{pics/atom/.style args={major #1 minor #2}{code={%  
\fill[red] (0,#2) arc (90:-90:#1 and #2);
\fill[green!50] (0,#2) arc (90:270:#1 and #2);
\draw (0,0) ellipse(#1 and #2);
}}}

\def\atompath{(0,0)--(\x,\y) pic{atom=major .4 minor \bb} node[right,scale=.6]{$+$} node[left,scale=.6]{$-$}}
        
\foreach \x in {-4,...,4}
\foreach \y in {-3,...,3}
{%
\pgfmathtruncatemacro\b{\x*\x+\y*\y}
\ifnum \b>0    
\pgfmathsetmacro{\bb}{.08*sqrt(\b)}
\ifnum \x<0 
\path[nodes={sloped,pos=1,xscale=-1}] \atompath;
\else
\path[nodes={sloped,pos=1}] \atompath;
\fi 
\fi
}
    
% central charge
\draw[fill=red] (0,0) circle(.18) node[scale=0.6]{$+$} + (-135:.4) node[red]{$q$};
\end{tikzpicture}
\end{document}
4
  • 2
    +1, very good thinking!! Aug 8, 2021 at 10:11
  • @JuanCastaño Thanks!
    – Black Mild
    Aug 8, 2021 at 10:14
  • 1
    I associate myself with @JuanCastaño +1.
    – Sebastiano
    Aug 8, 2021 at 10:38
  • My previous code gave wrong positions for + and - on the left part. Just fixed it!
    – Black Mild
    Aug 8, 2021 at 16:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.