4

I have two paths and I'm trying to create a new path that starts on the first path and switches from pathone to pathtwo when the two intersect, and then again follows the pathone when the two paths intersect again. Here is what I have:

\documentclass{standalone}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{intersections}  
\begin{document}
\begin{tikzpicture}
    \pgfmathsetmacro\minX{2}
    \pgfmathsetmacro\maxX{10}
    \pgfmathsetmacro\minY{4}
    \pgfmathsetmacro\maxY{10}
    \pgfmathsetmacro\CX{11}
    \pgfmathsetmacro\CY{7}
    \pgfmathsetmacro\CR{2}
    \pgfmathsetmacro\Roundness{0.2}
    \begin{scope} [local bounding box=BoxWest]
    \def\pathone{(.5*\maxX + .5*\minX,\maxY) 
        -- (-\Roundness + \maxX,\maxY)
        arc (90:0:\Roundness)
     -- (\maxX,\minY +\Roundness)
        arc (360:270:\Roundness)
        -- (.5*\maxX+ .5*\minX,\minY )}
        \path [name path=pathone, draw=green] \pathone;         
        \path [name path=pathtow, draw=blue](\CX,\CY)
        circle (\CR);   
         \path [name intersections={of = pathone and pathtwo}];
         \coordinate (A)  at (intersection-1);
         \coordinate (B)  at (intersection-2);
\end{scope}
\end{tikzpicture}
\end{document}

So far I have been able to create the two paths and find their intersecting points but I don't know how to create the new path as I explained.The Two paths

M.M.
  • 75
  • Path joins are not supported by TikZ. You can switch to a more powerful graphical software such as InkScape etc. and then export your graphics as TikZ code. – percusse Mar 23 '18 at 21:18
  • (i) welcome to tex.se! (ii) your code has error: pathtwo is not defined. please test you code and corret it. – Zarko Mar 23 '18 at 21:19
  • In this case you could cheat by clipping, but I guess you want a general solution, do you? @Zarko It's a typo pathtow. –  Mar 23 '18 at 21:44

2 Answers2

5

The intersection points and the angles for the arc can be easily calculated. There is a right triangle with the center point of the circle, a intersection point and a vertical and horizontal line. The length of the vertical line can be calculated with the theorem of Pythagoras, and an angle of the right triangle (half of the segment angle) can be calculated by the law of cosines.

\documentclass[margin=5pt]{standalone}
\usepackage{tikz}
\begin{document}
  \begin{tikzpicture}[x=10pt, y=10pt]
    \pgfmathsetmacro\minX{2}
    \pgfmathsetmacro\maxX{10}
    \pgfmathsetmacro\minY{4}
    \pgfmathsetmacro\maxY{10}
    \pgfmathsetmacro\CX{11}
    \pgfmathsetmacro\CY{7}
    \pgfmathsetmacro\CR{2}
    \pgfmathsetmacro\Roundness{0.2}

    \pgfmathsetmacro\OneWestX{.5*\maxX + .5*\minX}
    \pgfmathsetmacro\OneEastX{\maxX}
    \pgfmathsetmacro\OneNorthY{\maxY}
    \pgfmathsetmacro\OneSouthY{\minY}

    \pgfmathsetmacro\DiffX{\CX-\OneEastX}
    \pgfmathsetmacro\DiffY{sqrt(\CR * \CR - \DiffX * \DiffX)}
    \pgfmathsetmacro\DiffAngle{acos(\DiffX/\CR)}

    \draw[rounded corners]
      (\OneWestX, \OneNorthY)
      -- (\OneEastX, \OneNorthY)
      -- (\OneEastX, \CY + \DiffY) % North intersection point
      arc[
        start angle=180 - \DiffAngle,
        delta angle=-360+2*\DiffAngle,
        radius=\CR,
      ]
      -- (\OneEastX, \OneSouthY)
      -- (\OneWestX, \OneSouthY)
    ;
  \end{tikzpicture}
\end{document}

Result

Adjust the line joins to your needs (it is not clear from the question). The example uses rounded corners to let TikZ do the calculations. Also, I have used the right part of the circle (not clear either). The left part is easier to specify.

Heiko Oberdiek
  • 271,626
  • Thanks for replying to my question. Your approach worked great for the case as I questioned. Then when I tried to move the circle around with respect to pathone it failed to produce the desired path. – M.M. Mar 25 '18 at 17:23
  • @M.M. Since I do not know, what you have done to move the circle, I cannot answer it. – Heiko Oberdiek Mar 25 '18 at 17:53
  • For example, I'm changing the \pgfmathsetmacro\CY{7} to \pgfmathsetmacro\CY{10}. So the circle intersects both horizontal and vertical part of pathtwo. – M.M. Mar 25 '18 at 18:02
  • @M.M. If the geometry is changed, then the formulas need to be changed as well according to the new geometry. – Heiko Oberdiek Mar 25 '18 at 18:08
  • I have a half rectangle and a circle. The circle is moving in y-direction from up to bottom of the half rectangle. – M.M. Mar 25 '18 at 18:13
  • @M.M. My answer is just showing, that math can help at the price of the calculations. If you are not willing to pay this price, try some of the methods of the other answers. – Heiko Oberdiek Mar 25 '18 at 18:26
  • Doing the math is not the issue, I actually prefer to do the math myself rather than using other methods. the problem is that I don't know how to create if statements in latex to figure out where the intersection of the two paths is located ( whether in the vertical part of path one or the horizontal part). If I could figure out how to do that, Then I'd definitely do the calculation myself. Actually, the other approach that I accepted is not providing me with the description of the path as I need it. – M.M. Mar 26 '18 at 13:04
3

Complete revision: The fillbetween library has all this implemented, I found this in this question.

\documentclass{article}
\usepackage{pgfplots} % loads tikz
\pgfplotsset{compat=1.15}
\usetikzlibrary{intersections,fillbetween} 
%\tikzset{fill between/optimize name intersections=true}
\begin{document}
It turns out that the \verb|tikzlibraryfillbetween| library has macros for these
cases.
Excerpts from the file \verb|tikzlibraryfillbetween.code.tex|:
\begin{verbatim}
\path[intersection segments={of=first and second, 
sequence=A0 -- B1 -- B3  A3[reverse] -- A1}];
\end{verbatim}
This seems to suggest that one should refer to paths as \verb|A| and \verb|B|.
However, from \verb|tikzlibraryfillbetween.code.tex| one can read off that the
relevant path names are \verb|A|, \verb|B|, \verb|L| and \verb|R|. From the
order it appears that \verb|A| and \verb|B| are more accurate if the first path
(\verb|A|) is above the second one (\verb|B|), whereas  \verb|L| and \verb|R|
apply if the first path (\verb|L|) is left of the second one (\verb|R|). One
also finds in \verb|tikzlibraryfillbetween.code.tex|:
\begin{verbatim}
% FIXME : this optimization needs much more work... I believe it
% would be stable enough, but it covers too few cases.
%/tikz/fill between/optimize name intersections=true,
\end{verbatim}
which is probably to be interpreted as that not everything works as it should.
Nonetheless, in the example at hand, it works fine.

\begin{tikzpicture}
    \pgfmathsetmacro\minX{2}
    \pgfmathsetmacro\maxX{10}
    \pgfmathsetmacro\minY{4}
    \pgfmathsetmacro\maxY{10}
    \pgfmathsetmacro\CX{11}
    \pgfmathsetmacro\CY{7}
    \pgfmathsetmacro\CR{2}
    \pgfmathsetmacro\Roundness{0.2}
    \def\pathone{(.5*\maxX + .5*\minX,\maxY) 
        -- (-\Roundness + \maxX,\maxY)
        arc (90:0:\Roundness)
     -- (\maxX,\minY +\Roundness)
        arc (360:270:\Roundness)
        -- (.5*\maxX+ .5*\minX,\minY )}
    \path[name path = pathone, draw,green] \pathone;
    \path[name path = pathtwo, draw,blue] (\CX,\CY) circle (\CR);
    \draw[red,very thick,rounded corners, intersection segments={of=pathone and pathtwo,
    sequence=L1--R2 L3}];
\end{tikzpicture}
\end{document}

enter image description here

No clipping, no computations by hand, just so.

Note, however, that this does not work inside your original scope (but I was anyway not sure whether I understand its purpose).

ORIGINAL ANSWER: Here is a cheating solution, you do not even need to compute the intersections since \clip does the job for you.

\documentclass{standalone}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usepackage{graphicx}
\usetikzlibrary{intersections}  
\begin{document}
\begin{tikzpicture}
    \pgfmathsetmacro\minX{2}
    \pgfmathsetmacro\maxX{10}
    \pgfmathsetmacro\minY{4}
    \pgfmathsetmacro\maxY{10}
    \pgfmathsetmacro\CX{11}
    \pgfmathsetmacro\CY{7}
    \pgfmathsetmacro\CR{2}
    \pgfmathsetmacro\Roundness{0.2}
    \begin{scope} [local bounding box=BoxWest]
    \def\pathone{(.5*\maxX + .5*\minX,\maxY) 
        -- (-\Roundness + \maxX,\maxY)
        arc (90:0:\Roundness)
     -- (\maxX,\minY +\Roundness)
        arc (360:270:\Roundness)
        -- (.5*\maxX+ .5*\minX,\minY )}
        \path [name path=pathone, draw=green] \pathone;         
        \path [name path=pathtwo, draw=blue](\CX,\CY)
        circle (\CR);   
         \path [name intersections={of =pathone and pathtwo}];
         \coordinate (A)  at (intersection-1);
         \coordinate (B)  at (intersection-2);
         \begin{scope}
         \clip (current bounding box.south west) rectangle (current bounding
         box.north east) --
          (\CX,\CY) circle (\CR);
         \draw [red] \pathone; 
         \end{scope}
         \begin{scope}
         \clip \pathone;
          (\CX,\CY) circle (\CR);
         \draw [red] (\CX,\CY) circle (\CR); 
         \end{scope}

\end{scope}

\end{tikzpicture}
\end{document}

enter image description here

Heiko's path is obtained by changing the last clip to

     \clip (current bounding box.south east) rectangle (current bounding
     box.north west) --\pathone;

enter image description here