遮蔽两条极坐标曲线之间的区域

遮蔽两条极坐标曲线之间的区域

我正在使用 Tikz,有两条极坐标曲线r=1.5+cos(t)r=1.5。我想填充(阴影)曲线之间的区域(图片上箭头所示)。我该怎么做?也许使用\clip或其他方法?

在此处输入图片描述

我试过了\tikzfillbetween但它在极坐标中表现得很奇怪。

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{arrows, intersections, fillbetween}
\begin{document}
\begin{tikzpicture}
\begin{axis}[grid = both]
    % Outer curve
    \addplot [data cs=polar, domain=0:360, samples=180, black,
        line width=1pt, smooth](x, {1.5+cos(x)});
    % Inner curve
    \addplot [data cs=polar, domain=0:360, samples=180, green,
        line width=1pt, smooth](x, 1.5);
\end{axis}
\end{tikzpicture} 
\end{document}

答案1

您可以使用intersection segments

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}% <- added!!
\usepgfplotslibrary{fillbetween}% <- changed
\begin{document}
\begin{tikzpicture}
\begin{axis}[grid = both,
    set layers% <- added
]
    % Outer curve
    \addplot [data cs=polar, domain=0:360, samples=180, black,
        line width=1pt, smooth,
        name path=outer
        ](x, {1.5+cos(x)});
    % Inner curve
    \addplot [data cs=polar, domain=0:360, samples=180, green,
        line width=1pt, smooth,
        name path=inner
        ](x, 1.5);
    % Filling
    \begin{pgfonlayer}{axis background}
      \fill [orange!30,
          intersection segments={
            of=inner and outer,
            sequence={L0--L1--R1[reverse]--R0[reverse]}
          }];
    \end{pgfonlayer}
\end{axis}
\end{tikzpicture} 
\end{document}

结果:

在此处输入图片描述


显示片段的示例:

在此处输入图片描述

\documentclass{article}
\usepackage{pgfplots}
\pgfplotsset{compat=1.15}% <- added!!
\usepgfplotslibrary{fillbetween}% <- changed
\begin{document}
\begin{tikzpicture}
\begin{axis}[grid = both,
    set layers% <- added
]
    % Outer curve
    \addplot [data cs=polar, domain=0:360, samples=180, black,
        line width=1pt, smooth,
        name path=outer
        ](x, {1.5+cos(x)});
    % Inner curve
    \addplot [data cs=polar, domain=0:360, samples=180, green,
        line width=1pt, smooth,
        name path=inner
        ](x, 1.5);
    % Filling
    \begin{pgfonlayer}{axis background}
        \fill [orange!30,
            intersection segments={
              of=inner and outer,
              sequence={L0--L1--R1[reverse]--R0[reverse]}
            }];
    \end{pgfonlayer}
\end{axis}
% Showing the segments
\begin{scope}[line width=2pt,->,font=\bfseries]
    \foreach[count=\i from 0] \c in {green,orange,purple}{
        \edef\temp{\noexpand\draw [\c,
            intersection segments={of=inner and outer,sequence={L\i}}]node[left]{L\i};}
        \temp}
     \foreach[count=\i from 0] \c in {blue,gray,yellow}{
         \edef\temp{\noexpand\draw [\c,
            intersection segments={of=inner and outer,sequence={R\i}}]node[right]{R\i};}
         \temp}
 \end{scope}
\end{tikzpicture} 
\end{document}

答案2

我找到了一个解决方案,也许不是最佳解决方案,但它可以推广。在(axis cs: {(1.5)*cos(\x)}, {(1.5)*sin(\x)})框架内,scope可以用形式r(\x)为 的任何极坐标方程代替 (both) 1.5

在此处输入图片描述

\documentclass{article}
\usepackage{pgfplots}
\usetikzlibrary{arrows, intersections, fillbetween}
\begin{document}
\begin{tikzpicture}
\begin{axis}[grid = both]
    % Outer curve
    \addplot [data cs=polar, domain=0:360, samples=180, black,
        line width=1pt, smooth](x, {1.5+cos(x)});
    % Inner curve
    \addplot [data cs=polar, domain=0:360, samples=180, green,
        line width=1pt, smooth](x, 1.5);
    % Shading        
    \begin{scope}
        % Frame (inversed)
        \path[clip] plot[domain=0:360, samples=180] 
            (axis cs: {(1.5)*cos(\x)}, {(1.5)*sin(\x)}) 
            -- (current page.north east) -- (current page.south east) 
            -- (current page.south west) -- (current page.north west) 
            -- (current page.north east);
        % framed plot
        \addplot [data cs=polar, domain=0:360, samples=180, draw=none,
            fill = yellow!40!white, fill opacity = 0.5,
            line width=1pt, smooth](x, {1.5+cos(x)});
    \end{scope}
\end{axis}
\end{tikzpicture} 
\end{document}

答案3

使用 MetaPost 来实现这一目的的方法,可能会引起人们的兴趣。

编辑 我的第一次尝试使用了非常方便的buildcycle宏,但我刚刚意识到,在这种特殊情况下,填充心形然后取消填充圆圈要简单得多。

\documentclass[border=3mm]{standalone}
\usepackage{luatex85, luamplib}
    \mplibsetformat{metafun}
\begin{document}
\begin{mplibcode}
vardef plrfcn(expr tmin, tmax, tstep)(text r_t) =
    save t; t := tmin;
    (r_t)*dir t forever: hide(t := t + tstep) exitunless t <= tmax; 
        .. (r_t)*dir t 
    endfor
    if t-tstep < tmax: hide(t := tmax) .. (r_t)*dir t fi    
enddef;
u = cm; xmin = -2; xmax = 3; ymax = -ymin = 2;
beginfig(1);
    % grid
    for x = xmin upto xmax:
        draw u*(x, ymin) -- u*(x, ymax) withcolor .8white;
        if x>xmin: label.bot(TEX("$" & decimal x & "$"), u*(x, ymin)) fi;
    endfor;
    for y = ymin upto ymax:
        draw u*(xmin, y) -- u*(xmax, y) withcolor .8white;
        label.lft(TEX("$" & decimal y & "$"), u*(xmin, y));
    endfor; 
    % polar curves and filled area
    path cardio, circle; 
    circle = (plrfcn(0, 359, 1)(1.5) .. cycle) scaled u;
    cardio = (plrfcn(0, 359, 1)(1.5 + cosd t) .. cycle) scaled u;
    fill cardio withcolor .25[white, yellow]; unfill circle;
    draw cardio; draw circle withcolor green;
endfig;
\end{mplibcode}
\end{document}

在此处输入图片描述

答案4

使用 PSTricks 的仅用于紧急情况的解决方案。

\documentclass[pstricks,border=1cm]{standalone}
\usepackage{pst-plot}

\begin{document}
\begin{pspicture}[algebraic,polarplot,plotpoints=100](-3,-3)(3,3)
    \psaxes[axesstyle=polar,tickcolor=gray!25,ylabelFactor=^\circ](3,0)
    \pscustom[fillstyle=solid,fillcolor=yellow!25]
    {
        \psplot{PiDiv2}{PiDiv2 neg}{1.5}
        \psplot{PiDiv2 neg}{PiDiv2}{1.5+cos(x)}     
    }   
    \psplot[linecolor=blue]{0}{TwoPi}{1.5}
    \psplot[linecolor=red]{0}{TwoPi}{1.5+cos(x)}        
\end{pspicture}
\end{document}

在此处输入图片描述

相关内容