用线的交点来绘制凸函数

用线的交点来绘制凸函数

我正在尝试绘制(在 TikZ 中)凸函数F构造为线性函数的最小值 F1F2F3F4.为了做到这一点,我倾向于使用所述线的交点来找到最小值,但线交点似乎不允许我这样做。具体来说,我有以下代码:

\documentclass{article}
\nonstopmode

\usepackage{tikz}

\usetikzlibrary{calc,intersections}

\begin{document}
\begin{tikzpicture}[scale=.5]

    \draw[-stealth] (0,0) -- (10,0) node [below right] {};
    \draw[-stealth] (0,0) -- (0,10) node [left=2] {};

    %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

    \foreach \a/\b [count=\i] in {60/1.7, 45/2.4, 30/3.7, 18/5.5} {
        \begin{scope}
            \clip (0,0) rectangle (10,10);
            \draw (0,\b) -- +(\a:20);
        \end{scope}
        \node [left] at (0,\b) {$f_\i$};
    }

    % the following doesn't work because the "intersection of" doesn't like
    % the coordinates, or so it seems
    %\def\lasta{90}\def\lastb{0}
    %\draw[red, thick] (0,0) 
    %    \foreach \a/\b [remember=\a as \lasta, remember=\b as \lastb]
    %        in {60/1.7, 45/2.4, 30/4, 23/5} -- 
    %        (intersection of (0,\lastb)--+(\lasta:20) and (0,\b)--+(\a,20));
\end{tikzpicture}
\end{document}

结果

我想用一条粗红线画出这个函数F从一般意义上讲,这是所有这些的逐点最小值。欢迎提出任何意见,但我的问题归结为:

我怎样才能取所述线的交点,而无需手动展开环路?

答案1

仅使用 TikZ 但具有函数。备注:我用samples=2它来画线,因为两个点就足够了,但m我们需要足够的点来找到正确的最小值。我使用了 Jake 答案的一部分。

\documentclass{article}
\usepackage{tikz}

\begin{document}

\begin{tikzpicture}[declare function={
    f(\t)=tan(60)*\t+1.7;
    g(\t)=tan(45)*\t+2.4;
    h(\t)=tan(30)*\t+3.7;
    i(\t)=tan(18)*\t+5.5;
    m(\t)=min(f(\t) ,g(\t) ,h(\t),i(\t));}] 

 \draw[very thin,color=gray] (-0.1,-0.1) grid (10.1,10);
 \draw[->] (-0.2,0) -- (10.2,0) node[right] {$x$};
 \draw[->] (0,-0.2) -- (0,10.2) node[above] {$y$};  

 \clip (-1,-1) rectangle (10,10);     
\foreach \func in {f,g,h,i}
\draw [blue, thin] plot [domain=0:10, samples=2] (\x,{\func(\x)});
\draw [red, thick] plot [domain=0:10, samples=100] (\x,{m(\x)}); 
\end{tikzpicture}

\end{document} 

在此处输入图片描述

答案2

这不是对问题的直接回答,而是对不同方法的建议:如果您使用 PGFplots 并将您的线条视为适当的函数,那么您可以简单地使用以下方法绘制凸函数\addplot {min(f,g,h,i)};

\documentclass{article}

\usepackage{pgfplots}


\begin{document}

\begin{tikzpicture}[/pgf/declare function={
    f=tan(60)*x+1.7;
    g=tan(45)*x+2.4;
    h=tan(30)*x+3.7;
    i=tan(18)*x+5.5;
    }
]
\begin{axis}[
    axis lines=left,    % no box
    domain=-1:20, samples=100, % evaluate functions from 0:20 with 100 samples
    xmin=0, ymin=0, ymax=10, % set y limits
    no markers, % don't mark each point
    unit vector ratio*=1 1 1, % length of x unit = length of y unit
    xtick=\empty, ytick=\empty, % no tick marks
    cycle list={} % all plots the same colour unless specified otherwise
]

\addplot [line width=3pt, red!50!white] {min(f,g,h,i)};
\foreach \function in {f,...,i} {
    \addplot [samples=2] {\function}; % straight lines only need two samples. Taken from Altermundus' answer.
}
\end{axis}
\end{tikzpicture}
\end{document}

答案3

我喜欢 Jake 的解决方案。但是,如果出于某些奇怪的原因你不想使用,pgfplots你可以使用这种name intersections方法。它看起来如下:

\documentclass{article}
\nonstopmode
\usepackage{tikz}
\usetikzlibrary{calc,intersections}
\begin{document}
  \begin{tikzpicture}[scale=.5]

    \draw[-stealth] (0,0) -- (10,0) node [below right] {};
    \draw[-stealth] (0,0) -- (0,10) node [left=2] {};
    \foreach \a/\b [count=\i] in {60/1.7, 45/2.4, 30/3.7, 18/5.5} {
        \begin{scope}
            \clip (0,0) rectangle (10,10);
            \draw[name path global=\i path] (0,\b) -- +(\a:20);
        \end{scope}
        \node [left] at (0,\b) {$f_\i$};
    }
    \coordinate (last) at (0,0);
    \foreach \i [count=\j] in {2,...,4}{
      \path[draw,red,thick, name intersections={of=\j path and \i path}] (last) -- (intersection-1) coordinate (last);
    }
    \path (0,5.5) +(18:20) coordinate (final);
    \clip (0,0) rectangle (10,10);
    \draw[red,thick] (last) -- (final);
  \end{tikzpicture}
\end{document}

结果:

凸函数

相关内容