9

I want to draw an arc with a given radius from the point the arc intersects with a given circle to the point where the arc intersects with another circle. I have been reading through a lot of the TikZ manual, but to no avail. Can anyone help?

This PDF (http://www.mycroft.ch/tikztest.pdf) (MWE below) is intended to illustrate the problem. There are four circles, a part of each I want to use as path. The resulting curved wedge is then to be filled in black.

The green arc is no problem, I have start angle and end angle for it. For the two orange arcs I only have one angle (the one near the red circle is just an estimate). For the red arc I have nothing (both ends are estimates, thought to illustrate).

Interestingly, I can calculate the intersections (marked by the red circles), but I cannot fathom how to draw an arc there.

Hopefully I am overlooking something incredibly obvious! Thanks.

\documentclass{article}

\usepackage{tikz}
\usetikzlibrary{intersections,scopes}
\tikzset{
  pics/carc/.style args={#1:#2:#3}{
    code={
      \draw[pic actions] (#1:#3) arc(#1:#2:#3);
    }
  }
}

\begin{document}
\begin{tikzpicture}

\draw [name path=three] (120:1.06) circle (1.9);
\draw [name path=four] (0:1.06) circle (2.12);
\draw [name path=five] (0:0.77) circle (2.41);
\draw [name path=two] (0:0) circle (1.06);

\draw[green, thick] (0:3.18) arc [radius=2.12, start angle=0, end angle=180]; 
\draw[orange, thick] (0:3.18) arc [radius=2.41, start angle=0, end angle=197]; 
\draw[orange, thick] (180:1.06) arc [radius=1.06, start angle=180, end angle=245]; 
\draw[red, thick, name intersections={of=five and three}] (intersection-2) circle (2pt) node {}; 
\draw[red, thick, name intersections={of=two and three}] (intersection-1) circle (2pt) node {}; 

{ [xshift=-0.53cm,yshift=0.918cm] \pic [red,thick] {carc=238:274:1.9}; }

\end{tikzpicture}

\end{document}
  • I'm sorry, I'm a little confused as to what's your question. Is it about how to fill a shape made of arcs, or is it about how to calculate the starting and ending angles of your arc? – LaX Apr 16 '15 at 16:43
  • Sorry for being unclear. The filling is no problem. The problem is the arc in red, where do I get starting/ending angles from? What I am struggling with, in part, is that the circle in which the arc lies is not centered in (0,0) but in (120:1.06). Hope this helped! – Thorsten Apr 16 '15 at 16:47
  • Oh OK, you mean how you could get a similar result while getting rid of the xshifts and yshifts options? – LaX Apr 16 '15 at 16:50
  • No, the xshift and yshift I just introduced because that red arc was not correctly placed otherwise. Basically I want to do the following: - Draw an arc, whose underlying circle is centered in (120:1.06) and the radius is (1.9). - Starting point of that arc should be where this circle intersects with the other circle ("five). - Ending point of that arc should be where the arc's underlying circle intersects with yet another circle ("two"). – Thorsten Apr 16 '15 at 16:53
  • 1
    You could try this clip: \clip[draw] (center) -- ($(center)!2.5!(A)$) -- ($(center)!2.5!(B)$) -- cycle;. I added coordinates to your intersections: \draw[red, thick, name intersections={of=five and three}] (intersection-2) circle (2pt) node[below] {$A$} coordinate (A), did the same for (B) and defined (center) with \coordinate (center) at (120:1.06);. Wrap the clip in a scope env., along with \draw [red,thick] (120:1.06) circle (1.9); for the arc. This is just an example with a clip, but obviously this solution is not very nice as you have to adapt the clip to your draw every time. – LaX Apr 16 '15 at 22:14
13

A solution which allows to draw intersection segments of any two intersections is available as tikz library fillbetween.

This library works as general purpose tikz library, but it is shipped with pgfplots and you need to load pgfplots in order to make it work:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{fillbetween}

\begin{document}

\begin{tikzpicture}

\draw [name path=red,red] (120:1.06) circle (1.9);
%\draw [name path=yellow,yellow] (0:1.06) circle (2.12);
\draw [name path=green,green!50!black] (0:0.77) circle (2.41);
\draw [name path=blue,blue] (0:0) circle (1.06);

% substitute this temp path by `\path` to make it invisible:
\draw[name path=temp1, intersection segments={of=red and blue,sequence=L1}];
\draw[red,-stealth,ultra thick, intersection segments={of=temp1 and green,sequence=L3}];

\end{tikzpicture}

\end{document}

enter image description here

The key intersection segments is described in all detail in the pgfplots reference manual section "5.6.6 Intersection Segment Recombination"; the key idea in this case is to

  1. create a temporary path temp1 which is the first intersection segment of red and blue, more precisely, it is the first intersection segment in the Left argument in red and blue : red. This path is drawn as thin black path. Substitute its \draw statement by \path to make it invisible.

  2. Compute the desired intersection segment by intersecting temp1 and green and use the correct intersection segment. By trial and error I figured that it is the third segment of path temp1 which is written as L3 (L = left argument in temp1 and green and 3 means third segment of that path).

The argument involves some trial and error because fillbetween is unaware of the fact that end and startpoint are connected -- and we as end users do not see start and end point.

Note that you can connect these path segments with other paths. If such an intersection segment should be the continuation of another path, use -- as before the first argument in sequence. This allows to fill paths segments:

\documentclass{standalone}

\usepackage{tikz}
\usepackage{pgfplots}
\usetikzlibrary{fillbetween}

\begin{document}

\begin{tikzpicture}

\draw [name path=red,red] (120:1.06) circle (1.9);
%\draw [name path=yellow,yellow] (0:1.06) circle (2.12);
\draw [name path=green,green!50!black] (0:0.77) circle (2.41);
\draw [name path=blue,blue] (0:0) circle (1.06);

% substitute this temp path by `\path` to make it invisible:
\draw[name path=temp1, intersection segments={of=red and blue,sequence=L1}];
\draw[red,fill=blue,-stealth,ultra thick, intersection segments={of=temp1 and green,sequence=L3}]  
    [intersection segments={of=temp1 and green, sequence={--R2}}]
;

\end{tikzpicture}

\end{document}

enter image description here

  • This looks as if it is the solution I have been searching for - but I get "Package pgf Error: The argument of 'sequence' has an unexp ected format near 'L1'. Please write something like A0 -- B1 -- A1. See the pgf package documentation for explanation." Any idea what's going wrong? – Thorsten Apr 20 '15 at 15:22
  • Ah - I remember that I got feedback about 0-based indexing being inconsistent with the rest of the intersection libraries and I added L<1-based-index> as alias for A<0-based-index>. Apparently, your version of pgfplots does not have the L/R syntax. Please substitute L by A and decrease the following integer by 1. – Christian Feuersänger Apr 20 '15 at 19:06
  • Ah, now it works. But while the arc is now constructed perfectly, I fail to put that into the entire path (of the four arcs) to create a to be filled structure. The point where it fails is that while now I have (more or less) coordinates for the start- and endpoints of "my" arc, I cannot connect it to the other arcs for which I cannot specifiy and endpoint, but only an angle. I tried to define the other segments in a similar way to what you did - but I seem to struggle with the syntax. Is it possible to read the polar coordinates from the arcs start- and endpoints and use the angle? – Thorsten Apr 22 '15 at 10:34
  • I have edited the answer, in the hope that this helps to connect segments. Let me know if you encounter problems. – Christian Feuersänger Apr 22 '15 at 15:53
7

This one is makes a nice example of using buildcycle with subpath in Metapost.

enter image description here

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

beginfig(1);

path A, B, C, D, F;

A = fullcircle scaled 240;
B = fullcircle scaled 200 shifted 20 right;
C = fullcircle scaled 100 shifted 30 left;
D = fullcircle scaled 180 shifted 60 left shifted 40 up;

F = buildcycle(subpath (0,5) of A, 
               subpath (4,7) of D, 
               subpath (6,4) of C,
               subpath (4,0) of B);

fill F withcolor .8[blue,white];
draw A; draw B; draw C; draw D;
endfig;
end.

Each fullcircle has eight points numbered counter-clockwise from 3 o'clock. So subpath (0,5) of A is the an arc of the first 5/8 of A running counter-clockwise. If you reverse the order of the arguments to subpath you get a reversed path, so subpath (4,0) of B is the upper half of B running clockwise.

The buildcycle works best with a sequence of overlapping paths all running in the same direction.

2

I assume that I haven't been overlooking anything really obvious (because then someone would have pointed it out, probably), so I chose the less appealing, but more or less sufficient way to figure out the angles by hand:

\path [name path=A] (0:0.77) circle (2.41);
\path [name path=B, rotate=120] (0:1.06) circle (1.9);

\fill[black, name intersections={of=A and B}] (-1.06,0) arc [radius=2.12, start angle=180, end angle=0] arc [radius=2.41, start angle=0, end angle=196.75] arc [radius=1.9, start angle=238, end angle=273.8] arc [radius=1.06, start angle=247.54, end angle=180]  -- cycle; 

Thanks!

  • 2
    I think, this should be extended by an MWE and a screenshot – user31729 Apr 20 '15 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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