我正在尝试绘制(在 TikZ 中)凸函数F构造为线性函数的最小值 F1、 F2、 F3和 F4.为了做到这一点,我倾向于使用所述线的交点来找到最小值,但线交点似乎不允许我这样做。具体来说,我有以下代码:
\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}
结果: