我正在尝试绘制扫描结果所示的图表:
绘制自定义形状曲线的正确方法是什么 --- 手绘工具对应物。我使用了快速曲线,但很难区分极值和拐点。
\begin{figure}
\centering
\bt[xscale=0.03,yscale=0.03]
%\draw (0,0) grid[step=10](200,120);
\coordinate(a) at (0,0);
\coordinate(b) at (20,0);
\coordinate(c1) at (25,2);
\coordinate(c) at (30,10);
\coordinate(d) at (48,50);
\coordinate(ce) at (65,90);
\coordinate(e) at (80,110);
\coordinate(f) at (90,100);
\coordinate(g1) at (89,98);
\coordinate(g) at (93,95);
\coordinate(h) at (100,103);
\coordinate(ci) at (102,103);
\coordinate(i) at (130,100);
\coordinate(cj) at (165,96.6);
\coordinate(j) at (170,95);
\coordinate(ccl) at (172,90);
\coordinate(cl) at (198,5);
\coordinate(l) at (200,0);
\coordinate(m) at (206,-10);
\coordinate(n) at (218,0);
\coordinate(o) at (222,8);
\coordinate(cp) at (232,-3);
\coordinate(p) at (240,0);
\coordinate(r) at (248,0);
\coordinate(z) at (260,0);
\draw[>=latex,->](0,-18)--(0,128)node[left]{$U$};
\draw[>=latex,->](0,0)--(270,0)node[right]{$t$};
\draw[red,semithick] (a)--(b);
\draw[red,semithick] (b) to%
[quick curve through={(c1)(c)(d)(ce)(e)(f)(g)(h)(ci)(i)}] (cj);
\draw[red,semithick] (cj) to%
[quick curve through={(j)(ccl)(cl)(l)(m)(n)(o)(cp)(p)(r)}] (z);
\et
\caption{Charakterystyczne parametry przebiegów impulsowych}
\label{rys:przebiegimpulsowy}
\end{figure}
结果是,只要移动任何一个点一点点,就很容易出错。有没有更好的方法呢?
答案1
我会使用操作来执行此操作to[in=,out=,looseness=]
,这样您需要指定坐标和斜率,松散度是一个可选参数,1
如果没有特别设置。这是我第一次尝试猜测点。顺便说一句:事实上,您的曲线不是时间函数,因为它反转:\coordinate(f) at (90,100);
在之前
\coordinate(g1) at (89,98);
,我改变了它。
代码
\documentclass[tikz,border=2mm]{standalone}
\usetikzlibrary{arrows}
\begin{document}
\newcounter{myc}
\newcommand{\setinitialcoordinates}[3]% x, y, slope in degrees
{ \xdef\lastx{#1}
\xdef\lasty{#2}
\xdef\lastslope{#3}
}
\newcommand{\drawpiece}[4][1]%[looseness] target x, target y, target slope
{ \pgfmathsetmacro{\colo}{mod(\value{myc},4)*20+20}
\stepcounter{myc}
\pgfmathsetmacro{\inslope}{mod(#4+180,360)}
\draw (\lastx,\lasty) to[out=\lastslope,in=\inslope,looseness=#1] (#2,#3);
%\draw[red!\colo!blue] (\lastx,\lasty) to[out=\lastslope,in=\inslope,looseness=#1] (#2,#3);
\xdef\lastx{#2}
\xdef\lasty{#3}
\xdef\lastslope{#4}
}
\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};
\setinitialcoordinates{0}{0}{0}
\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece{25}{2}{45}
\drawpiece{30}{10}{70}
\drawpiece{48}{50}{80}
\drawpiece{65}{90}{70}
\drawpiece{80}{110}{0}
\drawpiece{89}{100}{-60}
\drawpiece{90}{98}{-30}
\drawpiece{93}{95}{0}
\drawpiece{100}{103}{3}
\drawpiece{102}{103}{0}
\drawpiece{130}{100}{-2}
\drawpiece{165}{96.6}{-10}
\drawpiece{170}{95}{-30}
\drawpiece{172}{90}{-70}
\drawpiece[0.2]{198}{5}{-85}
\drawpiece{200}{0}{-60}
\drawpiece{206}{-10}{0}
\drawpiece{218}{0}{60}
\drawpiece{222}{8}{0}
\drawpiece{232}{-3}{0}
\drawpiece{240}{0}{-5}
\drawpiece{248}{0}{1}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}
\end{document}
输出
编辑1
第一次尝试看起来不太好,但我认为主要是因为我使用了你提供的所有点。如果你只使用极值和拐点,效果会好得多:
代码 1
\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};
\setinitialcoordinates{0}{0}{0}
\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece[0.5]{80}{110}{0}
\drawpiece{93}{95}{0}
\drawpiece{102}{103}{0}
\drawpiece[0.5]{165}{96.6}{-10}
\drawpiece[0.3]{206}{-10}{0}
\drawpiece[0.7]{222}{8}{0}
\drawpiece{232}{-5}{0}
\drawpiece{248}{2}{0}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}
输出 1
正如您所说,您当前的解决方案对微小的变化非常敏感,以下是同样的事情,只是 x 坐标和膝盖角度不同:
代码 2
\begin{tikzpicture}[x={(0:0.03cm)},y={(90:0.03cm)}]
\draw[step=10,densely dotted, thin,gray] (0,0) grid (260,110);
\draw[-stealth,thick] (-5,0) -- (265,0) node[right] {$t$};
\draw[-stealth,thick] (0,-5) -- (0,115) node[left] {$U$};
\setinitialcoordinates{0}{0}{0}
\begin{scope}[red,very thick]
\drawpiece{20}{0}{0}
\drawpiece[0.5]{60}{110}{0}
\drawpiece{110}{95}{0}
\drawpiece{120}{103}{0}
\drawpiece[0.5]{140}{96.6}{-40}
\drawpiece[0.3]{170}{-10}{0}
\drawpiece[0.7]{200}{8}{0}
\drawpiece{220}{-5}{0}
\drawpiece{240}{2}{0}
\drawpiece{260}{0}{0}
\end{scope}
\end{tikzpicture}
答案2
我意识到这不是仅适用于 LaTeX 的解决方案,因此它可能不令人满意,但我最近必须使用类似的情节来做到这一点,这就是我所做的。
我曾经pgfplots
定义过一个分段函数,其各个部分都是满足我想要的约束条件(经过一个点、在某个点处有某个导数等)的最小次数插值多项式。不幸的是,我不知道如何从 tike/pgfplots 中获取插值多项式……您可以使用外部小程序、python、mathematica 等。
结果看起来不错:
\documentclass{article}
\usepackage{pgfplots}
\begin{document}
\pgfmathdeclarefunction{MyF}{1}{%
\pgfmathparse{%
(and (1 , #1<=5)*(3.-0.5*#1-2.24667*#1^2+2.93766*#1^3-1.55322*#1^4+0.413019*#1^5-0.0534444*#1^6+0.00265741*#1^7)) +%
(and (5<#1 , #1<7)*(4)) +%
(and (7<=#1 , #1<12)*(131.4-156.613*#1+54.0096*#1^2-7.99267*#1^3+0.538*#1^4-0.0135556*#1^5)) +%
(and (12<=#1 , 1)*(1)) %
}%
}
\begin{center}
\begin{tikzpicture}
\begin{axis}[axis lines = middle,minor tick num = 1, grid = both, xlabel = $t$, ylabel = $x$, no markers, smooth,xmin=0, xmax=14, ymin=-6, ymax=6, samples = 100, thick]
\addplot +[very thick, domain=0:14] {MyF(x)};
\end{axis}
\end{tikzpicture}
\end{center}
\end{document}