9

The following approach to Riemann Sums first draws an arbitrary curve (which may later be tweaked), then forms rectangles based upon intersections. Unfortunately, the filled rectangles hide portions of the curve. The path and rectangles, however, can not be interchanged since the rectangles depend upon the path coordinates. How can this problem be avoided without dramatically altering the approach?

Ps. I tried simply redrawing the curve after the rectangles but, for some reason, I cannot draw ANYTHING beyond the given code without prompting an error message. Something is wrong.

\documentclass{article}

\usepackage{tikz} 
\usetikzlibrary{intersections}

\begin{document}

\begin{tikzpicture}
%axis 
\draw (-.5,0) -- (6.5,0);  

%curve  
\draw[yshift=1cm,name path=curve] (-.5,0) %vertically shiftable
    to[out=70,in=180] (.7,1.5)
    to[out=0,in=180] (2,.5)
    to[out=0,in=180] (4.5,2.5)
    to[out=0,in=160] (6.5,1);

%rectangles
\foreach \x in {0,1,2,5}{
    \path[name path=line \x] (\x,0) -- (\x,4);
    \path[name intersections={of=curve and line \x, by={isect \x}}];    
    \draw[fill=gray!50] (isect \x) rectangle (\x+1,0);
    \draw[fill] (isect \x) circle [radius=2pt];
    }
\end{tikzpicture}

\end{document}
  • This post changes the opacity of the rectangle coloring. Adding ,opacity=0.4 after setting the color gray!50 will allow you to see the curve. – DJP Dec 18 '13 at 5:44
  • @DJP I tried this, but it has no effect. – steven_nevets Dec 18 '13 at 6:03
  • works for me, and then intensify the color. Try \draw[fill=gray,opacity=0.64] (isect \x) rectangle (\x+1,0); – DJP Dec 18 '13 at 6:05
  • @DJP For some reason, it doesn't render properly using DVIPS in Yap, but it works with PDF. Thanks. – steven_nevets Dec 18 '13 at 6:27
  • In fact, this seems to be connected to my difficulty adding additional code. If I add, say, \draw (0,0) circle [radius=1cm]; it won't compile using DVIPS, but will compile with PDF. I don't get it. – steven_nevets Dec 18 '13 at 6:35
9

I don't know what causes the problem with not being able to draw after that \foreach, but a different way is to use the backgrounds library to place the rectangles on the bottom layer.

enter image description here

\documentclass{article}

\usepackage{tikz} 
\usetikzlibrary{intersections,backgrounds}

\begin{document}

\begin{tikzpicture}
%axis 
\draw (-.5,0) -- (6.5,0);  

%curve  
\draw[yshift=1cm,name path=curve] (-.5,0) %vertically shiftable
    to[out=70,in=180] (.7,1.5)
    to[out=0,in=180] (2,.5)
    to[out=0,in=180] (4.5,2.5)
    to[out=0,in=160] (6.5,1);

%rectangles
\begin{scope}[on background layer]
\foreach \x in {0,1,2,5}{
    \path[name path=line \x] (\x,0) -- (\x,4);
    \path[name intersections={of=curve and line \x, by={isect \x}}];    
    \draw[fill=gray!50] (isect \x) rectangle (\x+1,0);
    \draw[fill] (isect \x) circle [radius=2pt];
    }
\end{scope}    
\end{tikzpicture}
\end{document}
  • T. This is a beautiful solution. Thank you. – steven_nevets Dec 18 '13 at 17:23
10

Using the code from Calling a previously named path in tikz, we can define the curve before drawing the rectangles but delay its rendering until afterwards.

\documentclass{article}
%\url{https://tex.stackexchange.com/q/150486/86}
\usepackage{tikz} 
\usetikzlibrary{intersections}

\makeatletter
\tikzset{
  use path for main/.code={%
    \tikz@addmode{%
      \expandafter\pgfsyssoftpath@setcurrentpath\csname tikz@intersect@path@name@#1\endcsname
    }%
  },
  use path for actions/.code={%
    \expandafter\def\expandafter\tikz@preactions\expandafter{\tikz@preactions\expandafter\let\expandafter\tikz@actions@path\csname tikz@intersect@path@name@#1\endcsname}%
  },
  use path/.style={%
    use path for main=#1,
    use path for actions=#1,
  }
}
\makeatother


\begin{document}

\begin{tikzpicture}
%axis 
\draw (-.5,0) -- (6.5,0);  

%curve  
\path[yshift=1cm,name path=curve] (-.5,0) %vertically shiftable
    to[out=70,in=180] (.7,1.5)
    to[out=0,in=180] (2,.5)
    to[out=0,in=180] (4.5,2.5)
    to[out=0,in=160] (6.5,1);

%rectangles
\foreach \x in {0,1,2,5}{
    \path[name path=line \x] (\x,0) -- (\x,4);
    \path[name intersections={of=curve and line \x, by={isect \x}}];    
    \draw[fill=gray!50] (isect \x) rectangle (\x+1,0);
    \draw[fill] (isect \x) circle [radius=2pt];
    }

\draw[use path=curve];

\end{tikzpicture}

\end{document}

Riemann sums

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.