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.

Case 1: Let's say I have a few coordinates (A), (B), (C), (W), (X), (Y), and (Z) (possibily obtained through intersection, rotation, and whatnots).

I draw two piecewise linear curves through (A), (B), (C) on one hand and (W), (X), (Y), and (Z) on the other hand.

Case 2: I have two curves defined by two functions, say f(x) = x + 3 and g(x) = - x + 2.

Case 3: One of the curves is defined by coordinates and the other by a function

In all these cases, is there a way to "add" both curves to obtain a third one (say h(x) = f(x) + g(x))?

For sake of simplicity, all curves I'm interested in at the moment have the nice property of being piecewise linear but feel free to relax this if there is an all encompassing solution.

Example for case 1:

\documentclass{minimal}
\usepackage{tikz}
\usetikzlibrary{calc,positioning}

\begin{document}

\begin{tikzpicture}
\newcounter{i}

% Curve 'one' .. is there a way to give it a name? 
% Coordinates saved for further labeling, and so on.
% How to do it smoothly?
\begin{scope}[red] 
  \setcounter{i}{0}%
  \foreach \point in {(0,4),(4,1),(10,6)} {%
    \node[coordinate] (one-\arabic{i}) at \point { };%
    \fill (one-\arabic{i}) circle (0.1);%
    \stepcounter{i}
  }
  \draw (one-0) -- (one-1) -- (one-2);
\end{scope}

% Curve 'two' .. 
% If I don't need to save the coordinates for later use, 
% there must be a better way to draw?
\begin{scope}[green] 
  \setcounter{i}{0}%
  \foreach \point in {(0,1),(3,5),(6,5),(10,2)} {%
    \node[coordinate] (two-\arabic{i}) at \point { };%
    \fill (two-\arabic{i}) circle (0.1);%
    \stepcounter{i}
  }
  \draw (two-0) -- (two-1) -- (two-2) -- (two-3);
\end{scope}

%%% What I want is the "sum" of curves one and two ...
\end{tikzpicture}

\end{document}
share|improve this question
    
I just provided a very simplistic example of what I want to do. –  green diod Sep 17 '12 at 9:34
add comment

1 Answer

up vote 8 down vote accepted

Here is a solution using intersections and calc libraries.

Method

  1. Draw and name (via name path) a first continuous path (x ranges 0 to 10).

  2. Draw and name (via name path) a second continuous path (x ranges 0 to 10).

  3. Foreach x in 0,...,100 :

    1. Draw and name a vertical line at x/10 (y ranges y-min to y-max of your paths).
    2. Search intersections (via name intersections) between this line and the first path and between this line and the second path (you should find a single intersection for each path).
    3. Calculate the sum of y-coordinates (via let operation) of these two intersections and create a new coordinate at (x/10, sum) named sum-x.
  4. Draw a line through points (sum-0) to (sum-100).

Result

some added curves

Code

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,intersections}

\begin{document}
\begin{tikzpicture}[line width=1pt]
  % a grid
  \draw[help lines] (0,-.5) grid (10,10);
  % x axis
  \draw[-latex,thick] (0,0) -- (10,0) node[right]{$x$};

  % red line
  \def\lineone{(0,4),(4,1),(8,6),(10,6)}
  \foreach \point[count=\c] in \lineone {%
    \coordinate[at=\point] (one-\c);%
    %\fill[red] (one-\c) circle (0.1);%
  }
  \draw[red,name path=one] (one-1) \foreach \i in {2,...,\c}{-- (one-\i)} node[right]{one};

  % blue line
  \def\linetwo{(0,1),(3,5),(4,2),(6,5),(10,2)}
  \foreach \point[count=\c] in \linetwo {%
    \coordinate[at=\point] (two-\c);%
    %\fill[blue] (two-\c) circle (0.1);%
  }
  \draw[blue,name path=two] (two-1) \foreach \i in {2,...,\c}{-- (two-\i)} node[right]{two};

  % one + two
  \foreach \c in {0,...,100} {
    \pgfmathsetmacro{\x}{\c/10}
    \path[name path=line] (\x,0) -- (\x,6);
    \path[name intersections={of=one and line,name=newone}];
    \path[name intersections={of=two and line,name=newtwo}];
    \path let \p1=(newone-1), \p2=(newtwo-1) in 
    (\x1,\y1+\y2) coordinate (sum-\c);
  }
  \draw[red!50!blue]
  (sum-0) \foreach \x in {1,...,100}{-- (sum-\x)} node[right]{one + two};

  % a green function
  \draw[green!50!black,name path=three]
  plot[domain=0:10,samples=100,smooth] (\x,{sin(3*\x r)+2}) node[right]{three};

  % one + three
  \foreach \c in {0,...,100} {
    \pgfmathsetmacro{\x}{\c/10}
    \path[name path=line] (\x,0) -- (\x,6);
    \path[name intersections={of=one and line,name=newone}];
    \path[name intersections={of=three and line,name=newthree}];
    \path let \p1=(newone-1), \p2=(newthree-1) in 
    (\x1,\y1+\y2) coordinate (sum-\c);
  }
  \draw[red!50!green!50!black]
  (sum-0) \foreach \x in {1,...,100}{-- (sum-\x)} node[right]{one + three};

  % a orange function
  \draw[orange,name path=four]
  plot[domain=0:10,samples=100,smooth] (\x,{cos(1*\x r)+4}) node[right]{four};

  % four + three
  \foreach \c in {0,...,100} {
    \pgfmathsetmacro{\x}{\c/10}
    \path[name path=line] (\x,0) -- (\x,6);
    \path[name intersections={of=four and line,name=newfour}];
    \path[name intersections={of=three and line,name=newthree}];
    \path let \p1=(newfour-1), \p2=(newthree-1) in 
    (\x1,\y1+\y2) coordinate (sum-\c);
  }
  \draw[orange!50!green!50!black]
  (sum-0) \foreach \x in {1,...,100}{-- (sum-\x)} node[right]{three + four};

\end{tikzpicture}
\end{document}
share|improve this answer
    
Wow!! Gorgeous!! Meanwhile, I looked around and saw this thread mentioning stack plots but it would have been really awkward. I wish there was some syntactic sugar for 'summing paths' –  green diod Sep 18 '12 at 9:41
    
Is there a pgf/tikz built-in way to know x/y-min and x/y-max of given plots? –  green diod Sep 18 '12 at 10:03
add comment

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.