6

I want to construct a figure that will be symmetrical polygons on the same base.

So, there is an equilateral triangle, a square, a pentagon, a hexagon, etc. one side of all these is the same horizontal line of, say, 5 c.m.

The brute force method I can think of is actually calculate the coordinates of different vertices and just draw lines in tikz.

But I am sure, (I hope, at least) that there is a more elegant, programatic way of doing the same thing.

Something like for i = 1 to n, etc.

But given my limited experience with tikz, I am not even able to dream it.

Any suggestions, help, pointers?

deshmukh
  • 2,435
  • 1
  • 26
  • 46

5 Answers5

10

You could use the TikZ polygon shapes in a \foreach loop. Add color and styles as you like.

Key points are

  • regular polygon shape of the shapes.geometric library
  • relative positioning of the positioning library
  • remember the last node, using characters a, b, ... for node names
  • using the south anchor for positioning and anchoring at the same base line
\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric, positioning}
\begin{document}
\begin{tikzpicture}
  \node (a) {};
  \foreach \i [remember=\i as \lastnode (initially a),
    count = \vertices from 3] in {b,...,i}
    \node [regular polygon, regular polygon sides=\vertices,
      minimum size=1cm, draw, right = 1.3cm of \lastnode.south,
      anchor=south] (\i) {};
\end{tikzpicture}
\end{document}

Polygons

And as I now understand, you may like to have the polygon to share one side of constant length, you could do it like above, keeping the south anchor but omitting relative positioning and letting TikZ calculate the width by:

minimum size = 5cm/(2*sin(180/\vertices))

Full code then:

\documentclass[border=10pt]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}
\begin{document}
\begin{tikzpicture}
  \node (a) {};
  \foreach \i [remember=\i as \lastnode (initially a),
    count = \vertices from 3] in {b,...,i}
    \node [regular polygon, regular polygon sides=\vertices, draw,
      minimum size = 5cm/(2*sin(180/\vertices)), anchor=south] (\i) {};
\end{tikzpicture}
\end{document}

Nested polygons

Stefan Kottwitz
  • 231,401
  • The second solution proposed by you was what I was looking for. Thanks and sorry if I did not word my question properly. And for some reason, I am not able to mention your name using @ notation. – deshmukh Aug 19 '15 at 04:50
7

As a single path:

\documentclass[tikz,border=5]{standalone}
\begin{document}
\tikz\draw (0,0) \foreach \i in {3,...,10}
  \foreach \j in {1,...,\i}{ -- ++(360/\i*\j:1) };
\end{document}

enter image description here

Mark Wibrow
  • 70,437
  • Amazing --- just five lines!! If you could add a few comments to explain how, that would be great. – deshmukh Aug 19 '15 at 04:54
  • @deshmukh (0,0) is the bottom right corner and the last angle will always be 360 (i.e. 0 = to the right) because then \i = \j. TikZ by default places the bottom of its picture on the baseline. – Qrrbrbirlbel Jan 25 '23 at 16:25
3

You can also do this very simply in plain Metapost. My poly_on routine will return the path of an n-sided polygon using the line between points a and b as a base.

enter image description here

prologues := 3;
outputtemplate := "%j%c.eps";

% return the path of a polygon with n sides 
% using points a and b as the base 
vardef poly_on(expr a,b,n) = 
  save s,t,c; pair c;
  s = 360/n;
  t = 90-180/n;
  c = whatever[a,b rotatedabout(a,+t)] 
    = whatever[b,a rotatedabout(b,-t)];
  for i=0 upto n-1: a rotatedabout(c,i*s) -- endfor cycle
enddef;

beginfig(1);
  for i=3 upto 10:
     draw poly_on((40i,0), (40i+100/i,0), i);
  endfor
endfig;

end.

This works by calculating the position of the centre from the two given points, then returning a path consisting of the first point rotated n times round this centre point. In the loop that draws them, I've made each side progressively shorter by adding 100/i to the second point each time.

Thruston
  • 42,268
3

As I understand the question, all the polygons should have the same side and should sit on a common base. Here's how to easily do it. \Multipol{<number>} builds regular polygones of 3,4,...,<number> sides all sitting on a common base.

enter image description here

The code:

\documentclass[border=4pt]{standalone}
\usepackage{tikz}

\newcommand\polygon[2][]{
  \pgfmathsetmacro{\angle}{360/#2}
  \pgfmathsetmacro{\startangle}{-90 + \angle/2}
  \pgfmathsetmacro{\Side}{4/(2*sin(\angle/2))}
  \pgfmathsetmacro{\Sideiii}{4/(2*sin(60))}
  \begin{scope}[#1]
    \foreach \i in {1,2,...,#2} 
    {
      \pgfmathsetmacro{\x}{\startangle + \angle*\i}
      \pgfmathsetmacro{\shift}{\Side*cos(180/#2)-\Sideiii*cos(180/3)}
      \draw[fill=blue!35,yshift=\shift cm] (\x:\Side) -- (\x + \angle:\Side);
    }
  \end{scope}
}
\newcommand\Multipol[2][]{%
\begin{tikzpicture}[#1]
  \foreach \Valor in {3,...,#2} 
  {
    \polygon{\Valor}
  }
\end{tikzpicture}%
}

\begin{document}

\Multipol{4}\qquad
\Multipol{7}\qquad
\Multipol{12}

\end{document}
Gonzalo Medina
  • 505,128
0

A pstricks way, with the pst-poly package:

\documentclass[x11names]{standalone}
\usepackage{ pst-poly}
\usepackage{auto-pst-pdf}
\colorlet{color3}{DarkSeaGreen2}
\colorlet{color4}{DarkSeaGreen3}
\colorlet{color5}{DarkSeaGreen4}
\colorlet{color6}{DarkSeaGreen4}
\colorlet{color7}{DarkSeaGreen3}
\colorlet{color8}{DarkSeaGreen2}

\begin{document}

\psset{unit=1.5cm, linewidth=1.5pt , dimen=m}
\begin{pspicture}%
    \multido{\I=3+1,\nx=0.0+2.0}{3}{\rput(\nx,\nx){\PstPolygon[PolyNbSides=\I, linecolor=color\I]}}
    \quad
    \multido{\I=6+1,\nx=7.0+2.0, \ny=4.0+ -2.0}{3}{\rput(\nx,\ny){\PstPolygon[PolyNbSides=\I, linecolor=color\I ]}}\\
    \rput(2,-2){\PstHeptagon[linecolor=Tan1,PolyOffset=2]}
    \rput(5.5,-2){\PstHeptagon[linecolor=Tan2,PolyOffset=3]}%
    \rput(9,-2){\PstOctogon[linecolor=Tan3, PolyOffset=3]}
\end{pspicture}

\end{document} 

enter image description here

Bernard
  • 271,350