19

I want to make a lens aperture with different f numbers(sizes of the holes). I started with this code but it wont make it look like a complete aperture. Appreciate any help.

\documentclass[aspectratio=43]{beamer}
\usepackage{tikz}


\begin{document}

\begin{frame}{Aperture image}

\begin{tikzpicture}
\clip (0,0) circle(1);
\draw[thick] (0,0) circle(1);
\foreach \r in {0,40,...,360}
\filldraw[fill = black!80,draw = white,thick, rotate = \r] (-3,-1) rectangle (-0.5,1);
\end{tikzpicture}
\end{frame}
\end{document}

The current output is looking like this. enter image description here

15
  • could you make your script compilable? Aug 5, 2019 at 4:57
  • Its compiling on my machine. I made it in beamer.
    – RD1153
    Aug 5, 2019 at 5:00
  • 2
    @RD1153, Raaja means can you please begin your code with \documentclass and end it with \end{document}. This means we can just copy and paste the whole block into an editor and saves us having to guess what class and packages you are using (only include packages you need for your code, not everything). And this is probably not beamer specific, so it's best to use a base class like article. Aug 5, 2019 at 5:11
  • 1
    Okay now I got it. Sorry about that.
    – RD1153
    Aug 5, 2019 at 5:12
  • 1
    @RD1153 Also, if you consider the answers to your previous questions useful, consider accepting them :) Aug 5, 2019 at 5:30

2 Answers 2

30

You could draw triangles instead of rectangles:

\documentclass{article}
\usepackage{tikz}
\begin{document}
\begin{tikzpicture}
  \clip (0,0) circle (1);
  \foreach \r in {0,40,...,320}
    \fill[black!80,rotate=\r] (-0.5,1) -- (-0.5,-0.13) --++ (130:1) -- cycle;
\end{tikzpicture}
\end{document}

enter image description here

4
  • Thanks lot for the answer. Could you please tell what the (130:1) is doing there?
    – RD1153
    Aug 5, 2019 at 7:55
  • @RD1153, that is polar coordinates (angle:length). The angle is taken from the horizontal, so to get a triangle with a 40° angle you need 90+40=130 Aug 5, 2019 at 7:58
  • The ++ makes the coordinate relative to the previous one. Aug 5, 2019 at 8:00
  • Okay thank you. Now I understand.
    – RD1153
    Aug 5, 2019 at 8:11
48

A little late, but the following defines a pic that is more or less configurable (and I promptly used it to create an animation). The calculations are most likely inefficient and the overall code doesn't look as good as those posted by the usual TikZ experts.

\documentclass[tikz]{standalone}

\tikzset
  {
    ,aperture segments/.initial = 6
    ,aperture radius/.initial = 3
    ,aperture closed/.initial = .5
    ,aperture/.pic={
      \begin{scope}
        \pgfkeysgetvalue{/tikz/aperture segments}\segments
        \pgfkeysgetvalue{/tikz/aperture radius}\rad
        \pgfkeysgetvalue{/tikz/aperture closed}\closed
        \pgfmathsetmacro\ang{360/\segments}
        \pgfmathsetmacro\endang{360-\ang}
        \pgfmathsetmacro\alphtild{(180-\ang)/2}
        \pgfmathsetmacro\rp{(1-\closed)*\rad}
        \pgfmathsetmacro\cc{\rad*sqrt(2*(1-cos(\ang)))}
        \pgfmathsetmacro\bp{sqrt(\rad*\rad+\rp*\rp-2*\rad*\rp*cos(\ang))}
        \pgfmathsetmacro\alphprim{asin(\rp/\bp*sin(\ang))}
        \pgfmathsetmacro\alph{\alphtild-\alphprim}
        \pgfmathsetmacro\bet{180-\ang-\alph}
        \pgfmathsetmacro\bb{\cc*sin(\bet)/sin(\ang)}
        \foreach \r in {0,\ang,...,\endang}
          {
            \filldraw[fill = black!80, draw = white, thick, rotate = \r]
              (0:\rad) ++(180-\alphprim:\bb) -- (0:\rad)
              arc[start angle=0, end angle=\ang, radius=\rad]
              -- cycle;
          }%
      \end{scope}%
    }
  }

\begin{document}
\foreach\x in {0,0.025,...,1}
  {
    \begin{tikzpicture}
      \pic [aperture segments=9, aperture closed=\x] {aperture};
    \end{tikzpicture}
  }
\foreach\x in {1,0.975,...,0}
  {
    \begin{tikzpicture}
      \pic [aperture segments=9, aperture closed=\x] {aperture};
    \end{tikzpicture}
  }
\end{document}

enter image description here

A small document which describes what is calculated above and why:

\documentclass[]{article}

\title{Aperture drawing}
\author{Skillmon}
\date{}

\usepackage{tikz}
\usepackage[]{amsmath}
\usepackage{array}
\usepackage{collcell}
\usepackage{booktabs}
\usepackage{siunitx}

\newcolumntype\mathcol[1]{>{\startmath}#1<{\endmath}}
\let\startmath\(
\let\endmath\)
\newcolumntype\macrocol[1]{>{\collectcell\makemacroname}#1<{\endcollectcell}}
\newcommand\makemacroname[1]
  {%
    \texttt{\expandafter\string\csname #1\endcsname}%
  }

\begin{document}
\maketitle

The geometry we use is shown in figure~\ref{fig:geom}.
In the equations below variables correspond to the names in the used
Ti\textit{k}Z code to draw the aperture. The correspondences are shown in
table~\ref{tab:corres}. In the following I don't care about the sign of the
angles denoted with $\angle P_1P_2P_3$ and always only care for their absolute
value, so $\angle P_1P_2P_3$ might actually be $\angle P_3P_2P_1$.

\begin{figure}
  \centering
  \begin{tikzpicture}
    \def\segments{9}
    \def\rad{3}
    \def\closed{0.3}
    \pgfmathsetmacro\ang{360/\segments}
    \pgfmathsetmacro\endang{360-\ang}
    \pgfmathsetmacro\alphtild{(180-\ang)/2}
    \pgfmathsetmacro\rp{(1-\closed)*\rad}
    \pgfmathsetmacro\cc{\rad*sqrt(2*(1-cos(\ang)))}
    \pgfmathsetmacro\bp{sqrt(\rad*\rad+\rp*\rp-2*\rad*\rp*cos(\ang))}
    \pgfmathsetmacro\alphprim{asin(\rp/\bp*sin(\ang))}
    \pgfmathsetmacro\alph{\alphtild-\alphprim}
    \pgfmathsetmacro\bet{180-\ang-\alph}
    \pgfmathsetmacro\bb{\cc*sin(\bet)/sin(\ang)}
    \draw 
      (0,0)       coordinate(O) circle [radius=1.5pt] node [below]{$O$}
      (0:\rad)    coordinate(A) circle [radius=1.5pt] node [below right]{$A$}
      ++(180-\alphprim:\bb)
                  coordinate(C) circle [radius=1.5pt] node [above left]{$C$}
      (\ang:\rad) coordinate(B) circle [radius=1.5pt] node [above right]{$B$}
      (\ang:\rp)  coordinate(D) circle [radius=1.5pt] node [below]{$D$}
      ;
    \draw[blue]
      (A) arc[start angle=0, end angle=40, radius=3cm] -- (C) -- cycle;
    \draw[gray, dashed]
      (O) -- (A)
      (A) -- (B)
      (O) -- (B)
      ;
  \end{tikzpicture}
  \caption
    {%
      The geometry in which we want to calculate the position of point $C$%
      \label{fig:geom}%
    }
\end{figure}

\begin{table}
  \centering
  \begin{tabular}{\mathcol{c} \macrocol{l} \mathcol{l}}
    \toprule
    \multicolumn{1}{l}{Variable} & \multicolumn{1}{l}{Macro name}
      & \multicolumn{1}{l}{Meaning} \\
    \midrule
    \bar{p} & closed & \overline{DB}/\overline{OB} \\
    n & segments \\
    r & rad & \overline{OA}=\overline{OB} \\
    \gamma & ang & \angle AOB \\
    \tilde{\alpha} & alphtild & \angle OAB \\
    r_p & rp & \overline{OD} \\
    c & cc & \overline{BA} \\
    b_p & bp & \overline{AD} \\
    \alpha' & alphprim & \angle OAC \\
    \alpha & alph & \angle CAB \\
    \beta & bet & \angle ABC \\
    b & bb & \overline{AC} \\
    \bottomrule
  \end{tabular}
  \caption
    {%
      Variable-Macro-Correspondence and their geometrical meaning in
      figure~\ref{fig:geom}.%
      \label{tab:corres}%
    }
\end{table}

The variables we know the values of are $n$, $r$, and $\bar{p}$. $\bar{p}$ is in
the range $[0,1]$ and describes how closed the aperture is. $n$ is the number of
aperture segments and $r$ is the outer radius of the aperture. From $n$ we get
the angle $\gamma = \angle AOB$ straight forward:

\begin{equation}
  \gamma = \frac{\ang{360}}{n}
\end{equation}
Also relatively easy to calculate are the value of $p$ and $r_p$:
\begin{align}
  p &= 1 - \bar{p} \\
  r_p &= rp
\end{align}
The next thing we want to know is the angle $\angle ACB$. We know how many edges
the polygon of the aperture will have ($n$), so we know the sum
of internal angles and $\angle ACB$ is the adjacent angle of one of the internal
angles:
\begin{equation}
  \angle ACB = \ang{180} - \ang{180}  \frac{(n - 2)}{n}
    = \ang{180} \cdot (1 - 1 + \frac{2}{n}) = \frac{\ang{360}}{n} = \gamma
\end{equation}
The distances $c$ and $b_p$ can be calculated using the law of cosines:
\begin{align}
  c &= \sqrt{2r^2 - 2r^2\cos \gamma} = r \sqrt{2(1-\cos\gamma)} \\
  b_p &= \sqrt{r^2 + r_p^2 - 2rr_p\cos\gamma} \label{eq:bp}
\end{align}
We could further simplify eq.~\ref{eq:bp}, but this should suffice.
$\tilde{\alpha}$ can be calculated with the sum of internal angles in the
triangle $OAB$ since it is isosceles. With the sine theorem we can calculate
$\alpha'$ and therefore $\alpha$ and $\beta$:
\begin{align}
  \tilde{\alpha} &= \frac{\ang{180}-\gamma}{2} \\
  \alpha' &= \arcsin ( \frac{r_p}{b_p}\sin\gamma ) \\
  \alpha &= \tilde{\alpha} - \alpha' \\
  \beta &= \ang{180} - \gamma - \alpha
\end{align}
Using the sine theorem again we calculate the value of $b$ and with the position
of $A$ and the angle $\alpha'$ we get the position of $C$:
\begin{equation}
  b = c \frac{\sin\beta}{\sin\gamma}
\end{equation}
In Ti\textit{k}Z the point $C$ is now positioned at
\verb|(0:\rad) ++(180-\alphprim:\bb)|. Now we can draw our aperture segments.
\end{document}
13
  • 1
    Wow. Very nice. It will be into my favorities. But the image it is very fast and too big. :-)
    – Sebastiano
    Aug 5, 2019 at 12:20
  • 3
    The result is magnificent. The answer would be much more educational if you added comments explaining the role of each variable and your calculations.
    – AndréC
    Aug 5, 2019 at 16:02
  • 1
    @Sebastiano The image isn't that big, 964k, but with 300dpi, and 3/100s per frame, which makes it look pretty smooth with the steps in use. You can just run the standalone document and after that convert -strip -alpha deactivate -layers OptimizePlus -density 300 -delay 3 -loop 0 aperture.pdf aperture.gif in the console.
    – Skillmon
    Aug 6, 2019 at 13:31
  • 1
    If I understand correctly, there is a typographical error: beta is the angle ABC and not the angle ACB.
    – AndréC
    Aug 7, 2019 at 8:16
  • 1
    @AndréC you're right, \beta should be \angle ABC, I'll correct this.
    – Skillmon
    Aug 7, 2019 at 9:13

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .