剪切路径时如何保留线帽?

剪切路径时如何保留线帽?

这个问题与在 TikZ 中禁用“剪辑”和“用作边界框”。是否可以剪切路径,但让线帽看起来像路径在剪切区域结束。

基本示例

\documentclass[border=10mm]{standalone}

\usepackage{tikz}

\tikzset{line/.style={blue,line width=10mm}}

\begin{document}
\begin{tikzpicture}
    \draw (0,0) grid (5,5);
    \clip (0,0) rectangle (5,5);
    \draw [line] (0,1)  -- (5,4);
\end{tikzpicture}
\end{document}

输出

输出

但期望的输出是

期望输出

我想以这种方式剪辑一个图,但我无法以域等于剪辑框的方式指定它,所以我必须使用剪辑框,但我不想丢失常规的线帽……

更现实的例子

情况1:我想yrange根据轴,但gnuplot将所有数据点写入表格文件,即使它们超出范围(它们o在第三列中用 标记,而i表示该点在范围内)。可以设置的xrange方式是,绘图从相同的值,但是这需要大量的尝试和错误,因为xrange必须为每个图找到单独的值。

案例 2:我得到了一条由一些点定义的曲线,其中第一个点和最后一个点必须是根,即= 0。问题是第二个根超出了轴的边界……我想我可以使用语法,(coord)!pos!(coord)但这是再次尝试并出错,让这条曲线在同一处结束X值作为情节。

\documentclass[border=10mm]{standalone}

\usepackage{tikz}

\tikzset{line/.style={blue,line width=10mm}}

\begin{document}
\begin{tikzpicture}
    \def\yzoom{50}% needed to prevent overflow
    % Axes
    \draw [<->] (0,0.07*\yzoom) |- (10.5,0);
    % Clip
    \clip (0,0) rectangle (10,0.07*\yzoom);
% CASE I
    % Plots
    \draw [line width=2pt,line cap=round]
        plot [smooth,raw gnuplot, id=\jobname-plot] function {%
            set xrange [1.4:10];
            set yrange [0:0.06*\yzoom];
            set samples 100;
            f(x) = \yzoom*(0.26/(x-1) - 1/(x**2));
            plot f(x);
        };
    \draw [line width=2pt,line cap=round]
        plot [smooth,raw gnuplot, id=\jobname-plot] function {%
            set xrange [1:10];
            set yrange [0:0.06*\yzoom];
            set samples 100;
            f(x) = \yzoom*(0.28/(x-1) - 1/(x**2));
            plot f(x);
        };
% CASE II
    % Curve, defined by three points.
    % P1 and P3 must have y=0
    \draw plot coordinates {(2,0) (5,2) (18,0)};
\end{tikzpicture}
\end{document}

未剪辑的输出:

现实示例,正常输出

输出被剪切,但圆头盖缺失……

现实示例,剪辑输出

答案1

线帽不是由 PGF 绘制的。它们实际上是 PDF/PS 特有的。因此,我对仅修改线帽以使其在剪辑后继续存在的可能性持相当悲观的态度。相反,我不知道有任何方便的 PGF 操作可以获取路径的一部分并将其保存以覆盖剪辑区域。理论上,可以走过曲线,但那太费力且太过粗略。

尽管您不喜欢它,但这里有一个例子,以防万一它可能会说服您并使您转向黑暗的一面。

\documentclass[border=10mm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.8}
\pgfplotsset{my style/.style={line width=2pt,line cap=round,no marks,smooth}}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
             restrict y to domain= 0:0.15,
             axis lines=left,
             enlargelimits={abs=0.5mm},
             xtick=\empty,ytick=\empty,
             axis line style={line width=2pt}
            ]
    \addplot+[my style,domain=1.4:10,samples=100] gnuplot {(0.26/(x-1) - 1/(x**2))};
    \addplot+[my style,domain=1.0:10,samples=100] gnuplot {(0.28/(x-1) - 1/(x**2))};
\end{axis}
\end{tikzpicture}
\end{document}

在此处输入图片描述

沒有\yzoom必須。

答案2

手册中说“忽略文件gnuplot中输出的行上两个数字后面的任何内容”并不完全正确。实际上,会检查第三列是否为(= 未定义)。如果我们也检查是否为,我们也可以跳过这一步(或者执行某种操作,如果这是必要的,对于中途超出范围的图,可能这样做)。.tableuo\pgfpathmoveto

当然,这不是真正的智能剪辑,因为线显然不会触及剪辑框的边框,我不得不将样本设置为(如果不是每次都调用,2000这可能不是问题),但它仍然是显而易见的。gnuplot

无担保。

这对于第二种情况没有帮助,但对于简单的直线,您可能包含一个预处理这三个点的宏,并包含正确的绘图坐标。

代码

\documentclass[tikz,convert=false,border=5mm]{standalone}
\tikzset{line/.style={blue,line width=10mm}}

\makeatletter
\def\pgf@parsegnuplotxyline#1 #2 #3\pgf@stop{%
  \edef\pgf@xyline@flag@val{#3}%
  \edef\pgf@xyline@flag@undef{u\space}%
  \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef%
  \else\edef\pgf@xyline@flag@undef{o\space}% not undef but "o"
    \ifx\pgf@xyline@flag@val\pgf@xyline@flag@undef%
%      \let\pgf@plot@first@action=\pgfpathmoveto% maybe needed if you go out of the box and in again
    \else
      \pgfplotstreampoint{\pgfpointxy{#1}{#2}}%
    \fi
  \fi%
}
\makeatother
\begin{document}
\begin{tikzpicture}
    \def\yzoom{50}% needed to prevent overflow
    % Axes
    \draw [ultra thick,<->] (0,0.07*\yzoom) |- (10.5,0);
    % Clip
    \draw[red] (0,0) rectangle (10,0.07*\yzoom);
% CASE I
    % Plots
    \draw [line width=2pt,line cap=round]
        plot [smooth,raw gnuplot, id=\jobname-plot] function {%
            set xrange [1.4:10];
            set yrange [0:0.07*\yzoom];
            set samples 2000;
            f(x) = \yzoom*(0.26/(x-1) - 1/(x**2));
            plot f(x);
        };
    \draw [line width=2pt,line cap=round]
        plot [smooth,raw gnuplot, id=\jobname-plot] function {%
            set xrange [1:10];
            set yrange [0:0.07*\yzoom];
            set samples 2000;
            f(x) = \yzoom*(0.28/(x-1) - 1/(x**2));
            plot f(x);
        };
%% CASE II
%    % Curve, defined by three points.
%    % P1 and P3 must have y=0
%    \draw plot coordinates {(2,0) (5,2) (18,0)};
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容