7

I'd like to use tikz to draw regular polygons that are too small for shapes.geometric. My goal is to have them in-line with the text:

In-line polygons

But when I try to write a tikzset to so I can quickly and easily draw any given polygon, I get an error ! Illegal unit of measure (pt inserted).

I think the issue is that I perform calculations on the argument of the tikzset inside the set that defines a for loop. But I don't know how get TeX to recognize the argument as numeric.

Here's my working code for the text above:

\documentclass[border=0.2cm]{standalone} \usepackage{tikz} \begin{document} \newdimen\R \R=0.1cm foo \begin{tikzpicture} % Indicate the boundary of the regular polygons \draw[xshift=2.5\R] (0:\R) \foreach \x in {90,180,...,359} { -- (\x:\R) } -- cycle (90:\R) ; \end{tikzpicture} baz \begin{tikzpicture} % Indicate the boundary of the regular polygons \draw[xshift=2.5\R] (0:\R) \foreach \x in {72,144,...,360} { -- (\x:\R) } -- cycle (90:\R) ; \end{tikzpicture} \end{document} 

(I got the code for the polygons here.)

And the broken code:

\documentclass[border=0.2cm]{standalone} \usepackage{tikz} \tikzset{ pics/Polygon/.style n args ={2}{% background code = { \draw[xshift=2.5*#2] (0:#2) \foreach \x in {360/#1,2*360/#1,...,360} { -- (\x:#2) } -- cycle (360/3:#2); } } } \begin{document} \begin{tikzpicture} \draw (0,0) pic {Polygon={5}{0.8cm}}; \end{tikzpicture} \end{document} 

From playing around with different options, I know the problem is that 360/#1 and 2*360/#1 don't work well in set used to define the for loop.

1
  • Why do you add a coordinate after the cycle? That's just a move-to to that point. Commented Jul 30, 2024 at 8:04

6 Answers 6

12

regular polygons that are too small for shapes.geometric

Set inner sep to zero to control their size through minimum size (which sets the radius).

Though, if you don't need it to be a node, there's no need to use the shape. It can be easily achieved with a sharp cycle plot which has a built-in loop.

As the drawing is so simple, I've also added a PGF version.

Code

\documentclass[varwidth, border=3pt]{standalone} \usepackage{tikz} \usetikzlibrary{shapes.geometric} \newcommand*\tikzPolygonShape[3][]{% \tikz[#1] \node[draw, inner sep=+0pt, minimum size={2*(#3)}, rotate=90-180/(#2), shape=regular polygon, regular polygon sides={#2}]{};} \newcommand*\tikzPolygonPlot[3][]{% \tikz[#1] \draw plot[sharp cycle, samples at={1, ..., #2}] ({\x*360/(#2)}:{#3});} \newcommand*\tikzPolygonPGF[2]{% \begin{pgfpicture} \pgfplotfunction{\x}{1, ..., #1}{\pgfpointpolar{\x*360/(#1)}{#2}} \pgfusepath{stroke} \end{pgfpicture}} \pgfset{foreach/eval col/.style={evaluate={\c=(\Sides00-300)/7;}}} \begin{document} foo \tikzPolygonShape{4}{.3em} baz \tikzPolygonShape{5}{.3em} --% \foreach[eval col] \Sides in {3, ..., 10}{ \tikzPolygonShape[red!\c!blue]{\Sides}{.3em}} foo \tikzPolygonPlot{4}{.3em} baz \tikzPolygonPlot{5}{.3em} --% \foreach[eval col] \Sides in {3, ..., 10}{ \tikzPolygonPlot[red!\c!blue]{\Sides}{.3em}} foo \tikzPolygonPGF{4}{.3em} baz \tikzPolygonPGF{5}{.3em} --% \foreach[eval col] \Sides in {3, ..., 10}{ \color{red!\c!blue}\tikzPolygonPGF{\Sides}{.3em}} \end{document} 

Output

enter image description here

1
  • One of a nice suggestion with character height and width Commented Jul 30, 2024 at 8:38
8
\documentclass[border=0.2cm]{standalone} \usepackage{tikz} \tikzset{ pics/Polygon/.style n args ={2}{% background code = { \draw[xshift=2.5*#2] (0:#2) \foreach \x [evaluate=\x as \angle using \x*360/#1] in {1,2,...,#1} {-- (\angle:#2)} -- cycle ; } } } \begin{document} \begin{tikzpicture} \draw (0,0) pic {Polygon={5}{0.8cm}}; \end{tikzpicture} \end{document} 

enter image description here

6

You just need to add parse = true to \foreach, \foreach[parse = true] ....

\documentclass[border=0.2cm]{standalone} \usepackage{tikz} \tikzset{ pics/Polygon/.style n args ={2}{% background code = { \draw[xshift=2.5*#2] (0:#2) \foreach[parse = true] \x in {360/#1,2*360/#1,...,360} { -- (\x:#2) } -- cycle (360/3:#2); } } } \begin{document} \begin{tikzpicture} \draw (0,0) pic {Polygon={5}{0.8cm}}; \end{tikzpicture} \end{document} 
6

You can also do this neatly with lualatex + luamplib using the Metapost support.

inline polygons

Compile this with lualatex.

\documentclass{article} \usepackage{luamplib} \newcommand\poly[1]{\ensuremath{\mathbin{\vcenter{\begin{mplibcode}beginfig(0); draw for i=1 upto #1: 3 dir (360 / #1 * (i-1)) -- endfor cycle; endfig;\end{mplibcode}}}}} \begin{document} foo \poly{4} baz \poly{5}. As a math binary: \(5 \poly{3} 7\). \end{document} 
5
\documentclass[border=0.2cm]{standalone} \usepackage{tikz} \tikzset{ pics/Polygon/.style n args={2}{background code={ \draw (0:#2) \foreach \x in {2,...,#1} {-- (-360/#1+360*\x/#1:#2)} -- cycle; }}} \begin{document} \begin{tikzpicture} \draw (0,0) pic {Polygon={5}{0.8cm}}; \end{tikzpicture} \end{document} 

enter image description here

3

If you like PS-Tricks, then try with the below:

\documentclass{book} \usepackage{pstricks-add} \usepackage{pst-poly} \begin{document} \begin{pspicture}[showgrid=false](-1,-1)(1,1) \PstPolygon[PstPicture=false] \end{pspicture} \end{document} 

enter image description here

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.