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}
6
  • 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, 2013 at 5:44
  • @DJP I tried this, but it has no effect. Dec 18, 2013 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, 2013 at 6:05
  • @DJP For some reason, it doesn't render properly using DVIPS in Yap, but it works with PDF. Thanks. Dec 18, 2013 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. Dec 18, 2013 at 6:35

2 Answers 2

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}
1
  • T. This is a beautiful solution. Thank you. Dec 18, 2013 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

You must log in to answer this question.

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