Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am learning tikz now, it is painfully slow, but I am slowly learning. I am trying to reproduce the image below.

What my desired output is

Here is my code so far. This is basically a rip of from the pgf manual.

\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}

\begin{document}

\begin{figure}[!htpb] \centering
\begin{tikzpicture}
\foreach \a in {5,...,5}{
 \draw[blue, dashed] (\a*2,0) circle(0.5cm);
\node[regular polygon, regular polygon sides=\a, minimum size=1cm, draw] at    (\a*2,0) {};
}
\end{tikzpicture}
\end{figure}
\end{document}

Some problems with this code

  • How do i scale this image?
  • How do I label each side ?
  • Once again, how do I make that pesky angle ?
  • Is there a way to do this for a n-gon?

When I scaled the image using simply \begin{tikzpicture}[scale=3]... only the circle grew. Labeling each point manually is sort of tedious.. =(


EDIT: I DID IT WOEEE Code us ugly though... :D:DD:

\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}

\pgfdeclarelayer{background}
\pgfdeclarelayer{foreground}
\pgfsetlayers{background,main,foreground}

\begin{document}

\begin{figure}[!htbp]
\centering
\Large 
\begin{tikzpicture}[scale=1]
\node (A) [draw,thick,regular polygon, regular polygon sides=6, minimum     size=7cm,outer sep=0pt,fill=gray!20] {};
\node at (A.corner 1) [anchor=360/6*(1-1)+270] {$D$};
\node at (A.corner 2) [anchor=360/6*(2-1)+270] {$E$};
\node at (A.corner 3) [anchor=360/6*(3-1)+270] {$F$};
\node at (A.corner 4) [anchor=360/6*(4-1)+270] {$A$};
\node at (A.corner 5) [anchor=360/6*(5-1)+270] {$B$};
\node at (A.corner 6) [anchor=360/6*(5-1)+270] {$C$};
\node at (A.corner 4) [right,above] {\hspace{3.5cm}$AB=16$cm};
\coordinate [label=above:\textcolor{blue}{$S$}] (S) at (0.95,1);
\draw[gray, thick, dashed] (0,0) circle(3.52cm);
\path[draw] (0.7,-0.3) node {$\alpha$};
{
\begin{pgfonlayer}{foreground}
\draw[gray,thick, dashed] (A.corner 4) -- (S) -- (A.corner 5);
\end{pgfonlayer}
}

\begin{scope}
  \path[clip] (S) -- (A.corner 4) -- (A.corner 5) -- cycle;
  \draw [red, fill=red!20] (S) circle (30pt);
  \draw [black] (S) circle (30pt);
\end{scope}
\end{tikzpicture}
\end{figure}
\end{document}
share|improve this question
    
About your last code. More compact is \foreach \V [count=\Vi from 1] in {D,E,F,A,B,C} {\node at (A.corner \Vi) [anchor=360/6*(\Vi-1))+270] {$\V$}; } But preferable is : \foreach \V [count=\Vi from 1] in {D,E,F,A,B,C} {\path (0,0) to [pos=1.1] node {$\V$} (A.corner \Vi); }. You don't need pgfonlayer. Remove the code with layers and you get the same result. –  Alain Matthes Nov 19 '11 at 10:13

3 Answers 3

up vote 9 down vote accepted

For scaling, add the transform shape option. That might not look too great though. You are probably better off modifying the minimum size and the circle. To label the sides you can use distance modifiers on the anchors, same for the corner points. For the angle you can either use tkz-euclid or (if you know the angle (or are willing to guess it like me)) you can just draw an arc. To generalize this to an n-gon, use a parameter instead of the for-loop (which does nothing now...) and draw using that. Of course the angle and the corresponging AB line won't be correct anymore, but the labelling will. This is what the code would look like:

\documentclass[10pt,a4paper]{article}
\usepackage{mathtools}
\usepackage{tikz}
\usetikzlibrary{calc}
\usetikzlibrary{backgrounds}
\usepgflibrary{shapes}
\usetikzlibrary{through}
\begin{document}
\begin{figure}[!htpb] \centering
\begin{tikzpicture}
\pgfmathsetmacro{\a}{6}
\newcounter{temp}
\draw[dashed] (\a*2,0) circle(3cm);
\node[regular polygon, regular polygon sides=\a, minimum size=6cm, draw, blue, fill=blue!20] (poly) at (\a*2,0) {};
\foreach [count=\side] \siide in {2,3,...,\a,1}{
  \pgfmathtruncatemacro{\opp}{mod(\side+\a/2,\a)}
  \pgfmathtruncatemacro{\opp}{ifthenelse(equal(\opp,0),\a,\opp)}
  \pgfmathtruncatemacro{\opi}{ifthenelse(equal(mod(\a,2),0),1,0)}
  \def\oppp{\ifnum\opi=0 poly.side \opp\else poly.corner \opp\fi}
  \node at ($(poly.side \side)!.15!270:(poly.corner \siide)$)  {\side};
  \node at ($(\oppp)!1.05!(poly.corner \side)$) {\setcounter{temp}{\side}\Alph{temp}};
}
\coordinate (S) at ($(poly.corner 5) + (100:3)$);
\begin{scope}
  \path[clip] (poly.corner 4) -- (S) -- (poly.corner 5) -- cycle;
  \path[draw,blue,fill=blue!50] (S) circle[radius=.4];
  \path (S) ++(255:.6) node {$\alpha$};
\end{scope}
\node at ($(poly.corner 4)!.5!(poly.corner 5)$) [above] {$DE = 16$cm};
\node at (S) [above] {S};
\path[draw,dashed] (poly.corner 5) -- (S) -- (poly.corner 4);
\end{tikzpicture}
\end{figure}
\end{document}

To clarify the code a little bit, the distance modifiers work as follows: (A)!x!a:(B) means take the point that is factor x on the line from A to B, then rotate it by a degrees around A. This allows us to place the labels roughly where we want them, without having to explicitly set them (the angles might need slight adjusting for larger polygons).

And the resulting output:

Tikz Hexagon

EDIT: Changed the code to place the labels to use the opposite corner. It uses the opposite side if the number of sides is odd. This way the placement of the labels will work for n-gons for pretty much any value of n. I also changed the angle to use the clipping approach instead of estimating it. Finally, I changed the way the node is drawn on the line, to ensure there is no difference in colour.

That makes the result looks like this, showing the normal hexagon and a 9-gon:

TikZ hexagon and 9-gon

share|improve this answer
    
Impressive. Now my solution looks like crap :p Removing this line from your code \node at ($(\oppp)!1.05!(poly.corner \side)$) {\setcounter{temp}{\side}\Alph{temp}}; Would this remove the labeling of the sides? =) –  N3buchadnezzar Nov 18 '11 at 14:38
    
@N3buchadnezzar: That would remove the labeling of the corners. To remove the labeling of the sides you need to remove: \node at ($(poly.side \side)!.15!270:(poly.corner \siide)$) {\side}; –  Roelof Spijker Nov 18 '11 at 14:46

Here a solution with tkz-euclide. With this method, there is no problem for scaling the picture. Now it's easy to build a regular polygon bases on two points. It's not very easy to use a node with the shape regular polygon because you don't know the center of this polygon if you need to construct the polygon from two vertices. The next method shows how to build this center with my package or directly with tikz. There is no problem to add label for side but it's more complicated to add labels for vertices. A simple solution is to use paths from the center G and the vertices. For the last questio, it's easy to draw a regular polygon with n sides. About my solution, it will be better to create a macro to build a regular polygon with two vertices or with a center and a vertex.

\documentclass{article}
\usepackage{tkz-euclide} 
\usetkzobj{all}   

\begin{document}

\begin{center}
\begin{tikzpicture} [scale=.8]% no problem with scale 
   \tkzDefPoint(-1,-2){A}  % with tikz you use coordinate 
   \tkzDefPoint(4,2){B} 
   \coordinate (S) at ($(A) + (60:7)$); % it's possible to use tikz's method 
   % \coordinate  (mAB) at ($(A)!.5!(B)$); with tkz-euclide we need
   \tkzDefMidPoint(A,B)\tkzGetPoint{mAB} 
     % 90*(n-2)/n with n sides to generalize the next method to get the center G
  \path let \p1 = ($ (mAB) - (A) $)
          in
   coordinate  (G) at ($ (mAB) ! veclen(\x1,\y1)*tan(60) !90: (B) $);  
   \tkzDrawCircle(G,A) with tikz you need to write
   %\node (H) [draw,circle through=(B)] at (G) {};
   % now I need to get others points of the polygon. It's possible to create a macro
   \tkzInterCC(B,G)(G,A)\tkzGetPoints{A}{C}
   \tkzInterCC(C,G)(G,A)\tkzGetPoints{B}{D}  
   \tkzInterCC(D,G)(G,A)\tkzGetPoints{C}{E}
   \tkzInterCC(E,G)(G,A)\tkzGetPoints{D}{F}   
   \tkzDrawPolygon[fill=blue!10](A,B,C,D,E,F)
   \tkzDrawSegments(F,S S,A)   
   \tkzDrawPoints(A,B,C,D,E,F,G,S)
   \tkzMarkAngle[mark=||,arc=lll,size=2 cm,mkcolor=red](F,S,A) 
   \tkzLabelAngle(F,S,A){$\alpha$}   
\end{tikzpicture}
\end{center}    
\end{document} 

It's possible to write the labels with tikz or with tkz-euclide

enter image description here

Update :

I realize that I have no macro to build regular polygons in tkz-euclide. You can find now on my site Altermundus a beta file named tkz-obj-polygons.tex that you can download here. A new version for the answer is :

\documentclass{article}
\usepackage{tkz-euclide} 
\usetkzobj{all}   
\begin{document} 


\begin{center}
\begin{tikzpicture} [scale=.75]
   \tkzDefPoint(-1,-2){A}  
   \tkzDefPoint(1,3){B} 
   \tkzDefRegPolygon[side,sides=6](A,B) \tkzGetPoint{O} 
   \tkzDrawPolygon[fill=black!10,draw=blue](P1,P2,P3,P4,P5,P6) 
   \tkzLabelRegPolygon[sep=1.05](O){A,...,F} 
   \tkzDrawCircle[dashed](O,A)
   \tkzLabelSegment[above,sloped,midway](A,B){\(A B = 16m\)}
   \foreach \i  [count=\xi from 1]  in {2,...,6,1} 
      {%
       \tkzDefMidPoint(P\xi,P\i)
       \path (O) to [pos=1.1] node {\xi} (tkzPointResult) ;} 
    \tkzGetRandPointOn[segment = P3--P5]{S}
    \tkzDrawSegments[thick,dashed,red](A,S S,B)
    \tkzDrawPoints(P1,P2,P3,P4,P5,P6,S)      
    \tkzLabelPoint[left,above](S){$S$} 
    \tkzDrawSector[R with nodes,fill=red!20](S,2 cm)(A,B)
    \tkzLabelAngle[pos=1.5](A,S,B){$\alpha$}    
\end{tikzpicture}
\end{center}      

\end{document}  

Explanations :

  1. \tkzDefRegPolygon is a macro to define regular polygon. With the option center you define a polygon with a center and a point but with the option side, you need to give two consecutive points of the polygon. By default, the number of sizes is 5 but the option sides can be used. If you use the option side you can find the center of the polygon with the macro \tkzGetPoint
  2. \tkzLabelRegPolygon is useful to add labels to vertices. The labels are placed on the line from the center trough the vertex.
  3. tkzGetRandPointOn is an old macro to get a random point. Here I get a point of the line CE.
  4. \tkzDrawSector is useful to fill a sector. You need to know the center and two points to define the start and the end. 2 cm is the radius of the filled sector.

Result :

enter image description here

share|improve this answer

I'm pleased to see that Altermundus has posted a method using tkz-euclide. There were two preliminary things that I wanted to say about this diagram and one of them was that if you're doing geometrical diagrams then you should take a look at the tkz packages (I don't know much about them myself but I've seen Altermundus do some pretty amazing diagrams here using them).

The other thing I wanted to say was that whilst it is tempting to use nodes to draw particular shapes, it has its drawbacks. Nodes are designed to hold text and some of their behaviours stem from that - in particular how they are affected by transformations. It is possible to circumvent these behaviours, but you do have to know how.

That's not an answer, though, more of a comment.

I do have an answer for you and one that doesn't use nodes.

\documentclass{article}
%\url{http://tex.stackexchange.com/q/35266/86}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
% This provides a translation from numbers to letters for labelling
% the vertices
\newcommand\numToAlpha[1]{\@Alph#1}
\makeatother

\begin{document}
\begin{tikzpicture}
% This draws the circle
\draw[dashed] (0,0) circle[radius=3cm];
% This draws,fills and labels the polygon
\draw[ultra thick,blue,fill=blue!25] (0,0)
% Set the number of sides
    let \n1=7 in
% We start so that the second line is the lower horizontal
% This means that the first vertex that we label is the left
% end of the lower horizontal
    ({-90 - 3*360/(2*\n1)}:3)
% Now we iterate over the edges
    \foreach \l in {1,...,\n1} {
% This saves our next angle (as we use it twice)
      let \n2={-90 + (2 * \l - 3) * 360/(2 * \n1)} in
% This draws the edge and labels it
% As our first edge is actually the last one, our label needs
% shifting round (modulo the number of edges)
      -- node[auto,swap,text=black] {\pgfmathparse{int(Mod(\l-2,\n1)+1)}\pgfmathresult}
% This is the endpoint of the edge
     (\n2:3)
% This is the label at the endpoint, we could have chosen to
% label the start of the edge, but then the offset would have
% been slightly more complicated.
% We also save these nodes since we'll want two of them later
     node[label={[text=black]\n2:{\numToAlpha{\l}}}] (\numToAlpha{\l}) {}
    };
% This is our point "S", I chose coordinates at random
\fill (1,.5) circle[radius=2pt] coordinate (S) node[above] {S};
% This draws the dashed lines to the edge
\draw[dashed] (A) -- (S) -- (B);
\begin{scope}
% My method for drawing the angle is sneaky: I clip a circle
% against the dashed path
\clip (A) -- (S) -- (B);
\draw[blue,ultra thick,fill=blue!50] (S) circle[radius=1cm];
\end{scope}
% Then to position the alpha, I use an invisible path that
% goes from S to the midpoint of A-B
\path ($(S)!1.2cm!($(B)!.5!(A)$)$) node {\(\alpha\)};
% Finally, we label the edge A-B with its distance
\path (A) -- node[auto] {\(A B = 16m\)} (B);
\end{tikzpicture}
\end{document}

Here's the result:

labelled n-gon

(Forgot a text=black. The code's correct but the numbers in the picture are blue instead of black.)

share|improve this answer
    
I agree with you about your remark about node. Sometimes is useful to draw some parts of geometrical diagrams with nodes but in some cases difficulty appears. For example if you want to draw a pentagon when you know a side given by two random points –  Alain Matthes Nov 19 '11 at 10:21
    
why not only \Alph{..} instead of \numToAlpha{...}? –  Herbert Nov 21 '11 at 11:05
    
@Herbert: presumably becuase \Alph takes a counter, not a number. \@Alph actually does the trick, I looked for such a command for quite some time before settling on the counter approach in my answer because I could not find it. Like the non-node solution by the way Andrew! –  Roelof Spijker Nov 21 '11 at 11:13
    
@Andrew Stacey: yes, you are right, I missed that point. A \let for numtoalph would be okay then –  Herbert Nov 21 '11 at 11:18
    
@Herbert: Yes to what you said. On both accounts. –  Loop Space Nov 21 '11 at 11:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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