15

enter image description here

Here is an illustration in which the angles are not accurately drawn.

I want to know whether there is an easier way to draw an accurate angle within a circle, say $\angle ABD = 15^\circ$.

Here is what I have done, from the very beginning:

\begin{tikzpicture}[scale=2]
    \coordinate (O) at (0,0);
    \draw (O) circle (1);
    \coordinate [label=above left:$A$] (A) at (105:1);
    \coordinate [label=below left:$B$] (B) at (225:1);
    \draw (A) -- (B);
\end{tikzpicture}

The next steps are draw angles of 15 and 30 degrees from the segment AB, to determine C and D (on the circle).

I wonder if this can be done easily using any TikZ packages?

4
  • Is this a math or a TikZ problem? Commented May 25, 2015 at 21:12
  • @Qrrbrbirlbel This is a TikZ problem. I want to draw this using TikZ. In Maths, we use compass and protractor to draw this. Commented May 25, 2015 at 21:13
  • may be used the angles package? texample.net/tikz/examples/angles-quotes
    – Nasser
    Commented May 25, 2015 at 21:22
  • @Nasser That was used to sketch (draw) the graph I posted in OP. But I dont think it can actually draw an accurate angle if I am not mistaken. It only labels the angles. tex.stackexchange.com/questions/246856/… Commented May 25, 2015 at 21:48

4 Answers 4

21

For compass and protractor constructions, one can actually just use the through library, the calc library and the intersection cs. The turn key can help to find relative polar coordinates.

The through library only provides one key which has to be used with a node: circle through.

It creates a node of the shape circle that has its center at the at part of the node and goes through the point given to the key. I am using the point (right:1) which is the compass-direction version of (0:1) (which is the polar version of (1, 0)).

This allows me to create a circle with dimensions that scales with the scale value without using transform shape or calculating stuff beforehand (which basically is handled by the through library). For different x scale and y scale or other transformations (setting the x and/or y vector for example) will most likely fail anyway, and you will need to use a circle/ellipse path operator. However, the intersection cs can only work with circle nodes and lines (or two lines or two circular nodes). It really is something for compass and protractors.

If the circle’s center (as in our example) does not lie on the origin, you will need to use circle through={([shift={(<center>)}]0:<radius>)}.


The naming of the node ci is needed for

  • the use with intersection cs as it needs the name of a (circular) node and
  • the use of its anchor-border where one can use arbitrary angles.

If you don’t use a circular node, instead of (ci.<angle>), you would use (<angle>:<radius>) or ([shift={(<center>)}]<angle>:<radius>).


The points can then be found with:

\usetikzlibrary{through, calc} % preamble

\begin{tikzpicture}[scale=2]
    \coordinate (O) at (0,0);
    \node[draw] (ci) at (O) [circle through=(right:1)] {};
    \coordinate [label=above left:$A$] (A) at (ci.105);
    \coordinate [label=below left:$B$] (B) at (ci.225);
    \path (A) -- (B) -- ([turn]-15:-1) coordinate (B')
          (B) -- (A) -- ([turn]30:-1) coordinate (A');
    \path (intersection cs: first node=ci, second line={(B)--(B')})
      coordinate[label=above:$C$] (C)
          (intersection cs: first node=ci, second line={(A)--(A')})
      coordinate[label=below right:$D$] (D);
    \draw (A) -- (B) -- (C) -- (D) -- cycle [line join=bevel];
\end{tikzpicture}

Unfortunately, this is not very accurate when it comes to circles:

enter image description here enter image description here


The intersections library can find intersections between arbitrary paths, not only circles and straight lines. However, a little more work is needed, as path need to be named and the used paths actually need to intersect.

\usetikzlibrary{through, intersections} % preamble

\begin{tikzpicture}[scale=2]
    \coordinate (O) at (0,0);
    \node[draw, name path=ci] (ci) at (O) [circle through=(right:1)] {};
    % or \draw [name path=ci] (O) circle[radius=1];
    \coordinate [label=above left:$A$] (A) at (ci.105);
    \coordinate [label=below left:$B$] (B) at (ci.225);
    \path[overlay] (A) -- (B) -- ([turn]-15:-3) coordinate (B');
    \path[overlay] (B) -- (A) -- ([turn]30:-3) coordinate (A');
    \path[overlay, name path=A] (A) -- (A');
    \path[overlay, name path=B] (B) -- (B');
    \path[name intersections=
      {of=A and ci, by={@,[label=below right:$D$]D}}]; % @ is not used (equals A)
    \path[name intersections={of=B and ci, by={[label=above:$C$]C}}];
    \draw (A) -- (B) -- (C) -- (D) -- cycle [line join=bevel];
\end{tikzpicture}

The solution is more correct:

enter image description here


You can also do the calculations beforehand

enter image description here

and just use TikZ for drawing:

\begin{tikzpicture}[scale=2]
    \coordinate (O) at (0,0);
    \node[draw] (ci) at (O) [circle through=(right:1)] {};
    \coordinate [label=above left:$A$]  (A) at (ci.105);
    \coordinate [label=below left:$B$]  (B) at (ci.225);
    \coordinate [label=      above:$C$] (C) at (ci.225-150);
    \coordinate [label=below right:$D$] (D) at (ci.105-180);
    \draw (A) -- (B) -- (C) -- (D) -- cycle [line join=bevel];
\end{tikzpicture}

enter image description here

7
  • For the first one , it is actually accurate enough but the scale is ruining the precision.
    – percusse
    Commented May 25, 2015 at 23:06
  • @Qrrbrbirlbel Please explain the command \node[draw] (ci) at (O) [circle through=(right:1)] {};. What are you calling ci? You label points on the circumference using it - \coordinate [label=above left:$A$] (A) at (ci.105);, for example. What does the option circle through=(right:1) instruct TikZ to draw?
    – Adelyn
    Commented May 25, 2015 at 23:54
  • Thanks! Just realized how easy it is to calculate the angles beforehand. Clearly I was not thinking straight and thought it would be difficult. Commented May 26, 2015 at 11:59
  • @percusse I don't think. If I use scale=1 but 2 as the radius for the circle I get the same output. Similar inprecision can be seen with scale=1 and radius of 1. Commented May 26, 2015 at 19:57
  • @Adelyn I've added some explanations. Do they help? The through library is explained in the manual. Commented May 26, 2015 at 20:36
13

Using the basic geometry of the circle, we can also draw this nicely in Metapost.

enter image description here

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

vardef angle_mark(expr a,b,c,s) =
  fullcircle scaled s rotated angle (a-b) shifted b cutafter (b--c)
enddef;

beginfig(1);

pair A, B, C, D;

path circle;

circle = fullcircle scaled 144;

A = point 2.818 of circle; % a random point on the circle
D = A rotated -30;
B = A rotated (132); % this one can be an arbitrary amount
C = B rotated 60;

label(btex $A$ etex, A scaled 1.1);
label(btex $B$ etex, B scaled 1.1);
label(btex $C$ etex, C scaled 1.1);
label(btex $D$ etex, D scaled 1.1);

dotlabel.bot(btex $O$ etex, origin);

path a[];
a1 = angle_mark(B,A,C,40);
a2 = angle_mark(D,B,A,70);
a3 = angle_mark(B,D,C,40);
draw a1 withcolor .7 white;
draw a2 withcolor .7 white;
draw a3 withcolor .7 white;
label.lrt(btex $30^\circ$ etex scaled 0.6, point 0.3 of a1);
label.top(btex $15^\circ$ etex scaled 0.6, point 0.55 of a2);
label.lrt(btex  $x^\circ$ etex scaled 0.6, point 0.25 of a3);

draw A -- B -- D -- C -- cycle;
draw circle withcolor .67 red;

endfig;
end.

The construction relies on the fact that if angle ∠AOD is 30° then ∠ABD=∠ACD=15°, and if angle ∠BOC is 60° then ∠BAC=∠BDC=30°. The relative rotation from A to B is irrelevant. It simplifies construction in Metapost to keep the centre at the origin, so that rotate can be used in a natural way.

0
8

This solution uses

  • the intercections library to calculate the intersection of lines AC and BD with the circle.
  • the calc library for the angles: ($(A)!2!30:(B)$) meaning ($(A)!<length>!<angle>:(B)$). Note: radius is 1, so diameter is 2. That's why a length of 2 will definitely intersect the circle.
  • clip everything outside the circle.

Code:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{calc,intersections}
\begin{document}
    \begin{tikzpicture}[scale=2]
        \coordinate[label=above left:$A$] (A) at (105:1);
        \coordinate[label=below left:$B$] (B) at (225:1);
        \draw[name path=circ] (0,0) circle (1);
        \begin{scope}
            \clip (0,0) circle (1);
            \path[name path=AC] (A) -- ($(A)!2!30:(B)$);
            \path[name path=BD] (B) -- ($(B)!2!-15:(A)$);
            \path[name intersections={of=AC and circ, by=C}];
            \path[name intersections={of=BD and circ, by=D}];
            \draw (A) -- (B) -- (D) -- (C) -- cycle;
        \end{scope}
        \node[below right] at (C) {$C$};
        \node[above right] at (D) {$D$};
    \end{tikzpicture}
\end{document}

EDIT: without clipping (as suggested by Heiko Oberdiek)

Without clipping, line join=bevel needs to be used. Also a better value than 2 needs to be used as length for the paths AC and BD. 1.2 seems to be a way better choice here.

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{calc,intersections}
\begin{document}
    \begin{tikzpicture}[scale=2]
        \coordinate[label=above left:$A$] (A) at (105:1);
        \coordinate[label=below left:$B$] (B) at (225:1);
        \draw[name path=circ] (0,0) circle (1);
        \path[name path=AC] (A) -- ($(A)!1.2!30:(B)$);
        \path[name path=BD] (B) -- ($(B)!1.2!-15:(A)$);
        \path[name intersections={of=AC and circ, by={[label=below right:$C$]C}}];
        \path[name intersections={of=BD and circ, by={[label=above right:$D$]D}}];
        \draw[line join=bevel] (A) -- (B) -- (D) -- (C) -- cycle;
    \end{tikzpicture}
\end{document}

enter image description here

EDIT 2: set (A) to (130:1)

If you change the \path of AC and BD to \draw you can see the actual intersections. So appropriate length values for AC a BD respectively are 1.3 and 1.4. To find intersection C, we need to get the second intersection of AC and circle, so we put a dummy argument as the first intersection:

\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{calc,intersections}
\begin{document}
    \begin{tikzpicture}[scale=2]
        \coordinate[label=above left:$A$] (A) at (130:1);
        \coordinate[label=below left:$B$] (B) at (225:1);
        \draw[name path=circ] (0,0) circle (1);
        \path[name path=AC] (A) -- ($(A)!1.4!30:(B)$);
        \path[name path=BD] (B) -- ($(B)!1.3!-15:(A)$);
        \path[name intersections={of=AC and circ, by={dummy,[label=below right:$C$]C}}];
        \path[name intersections={of=BD and circ, by={[label=above right:$D$]D}}];
        \draw[line join=bevel] (A) -- (B) -- (D) -- (C) -- cycle;
    \end{tikzpicture}
\end{document} 

enter image description here

6
  • 1
    There is an alternative for clipping here: line join=bevel. Commented May 26, 2015 at 5:30
  • 1
    @HeikoOberdiek Clipping also clips the paths AC and BD. But choosing a more reasonable value than 2 for the length of those paths will solve this too. Made an edit. Commented May 26, 2015 at 8:52
  • If I change the position of $A$ to (A) at (130:1). I got a wired result, of which the position of $C$ is in the circle, even after I change the length key. Commented May 26, 2015 at 12:13
  • @ChenStatsYu In the case of (A) at (130:1) you'll need the second intersection of AC and circ. So use a dummy as the first intersection. See my edit. Commented May 26, 2015 at 14:41
  • 1
    @benedito \fill[red] (A) -- (C) -- (D); Commented Jul 20, 2015 at 14:59
8

Another MetaPost solution. Thruston was quicker than me for that one :-). My own solution, although following the same basic principles for placing C and D, is a bit different: it uses ready-to-use macros from the Metafun format to draw the angles (anglebetween and anglelength) and to place the labels nicely around the circle (freelabel). So I thought it could be useful to post it all the same.

Included in a LuaLaTeX program for typesetting convenience:

\documentclass[border=2mm]{standalone}
\usepackage{luamplib, gensymb}
  \mplibsetformat{metafun}
  \mplibtextextlabel{enable}
\begin{document}
  \begin{mplibcode}
    u = 3.5cm;
    path circle; circle = fullcircle scaled 2u;
    pair A, B, C, D; 
    A = u*dir 105; 
    B = u*dir 225;
    C = B rotated 60;
    D = A rotated -30;
    beginfig(1);
      draw circle;
      draw A--B--D--C--cycle;
      forsuffixes M = A, B, C, D: freelabel("$" & str M & "$", M, origin); endfor
      anglelength := cm;
      draw anglebetween(A--B, A--C, "$30\degree$");
      draw anglebetween(D--B, D--C, "$x\degree$");
      anglelength := 2cm;
      draw anglebetween(B--A, B--D, "$15\degree$");
    endfig; 
  \end{mplibcode}
\end{document}

Output:

enter image description here

You must log in to answer this question.

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