答案1
这至少是一个开始。您可以定义一个函数,以数值方式计算给定函数的梯度分量。然后,您执行一个循环,从前一个坐标生成下一个坐标,并在前一个坐标处生成梯度。像往常一样,可能存在许多变化(我希望这不会导致许多评论要求说明这些变化 ;-)。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\tikzset{arrowed/.style={decorate,
decoration={show path construction,
moveto code={},
lineto code={
\draw[#1] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
curveto code={},
closepath code={},
}},arrowed/.default={-stealth}}
\usepackage{pgfplots}
\pgfplotsset{gradient function/.initial=f,
dx/.initial=0.01,dy/.initial=0.01}
\pgfmathdeclarefunction{xgrad}{2}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\edef\myfun{\pgfkeysvalueof{/pgfplots/gradient function}}%
\pgfmathparse{(\myfun(#1+\pgfkeysvalueof{/pgfplots/dx},#2)%
-\myfun(#1,#2))/\pgfkeysvalueof{/pgfplots/dx}}%
% \pgfmathsetmacro{\mysum}{\mysum+\myfun(\value{isum},#2)}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfmathdeclarefunction{ygrad}{2}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\edef\myfun{\pgfkeysvalueof{/pgfplots/gradient function}}%
\pgfmathparse{(\myfun(#1,#2+\pgfkeysvalueof{/pgfplots/dy})%
-\myfun(#1,#2))/\pgfkeysvalueof{/pgfplots/dy}}%
% \pgfmathsetmacro{\mysum}{\mysum+\myfun(\value{isum},#2)}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfplotsset{compat=1.17}
\begin{document}
\begin{tikzpicture}
\begin{axis}[width=12cm,%
declare function={f(\x,\y)=cos(deg(\x)*0.8)*cos(deg(\y)*0.6)*exp(0.1*\x);}]
\addplot3[surf,shader=interp,domain=-4:4,%samples=81
]{f(x,y)};
\edef\myx{0.15} % first x coordinate
\edef\myy{-0.15} % first y coordinate
\edef\mystep{-2}% negative values mean descending
\pgfmathsetmacro{\myf}{f(\myx,\myy)}
\edef\lstCoords{(\myx,\myy,\myf)}
\pgfplotsforeachungrouped\X in{0,...,5}
{
\pgfmathsetmacro{\myx}{\myx+\mystep*xgrad(\myx,\myy)}
\pgfmathsetmacro{\myy}{\myy+\mystep*ygrad(\myx,\myy)}
\pgfmathsetmacro{\myf}{f(\myx,\myy)}
\edef\lstCoords{\lstCoords\space (\myx,\myy,\myf)}
}
\addplot3[samples y=0,arrowed] coordinates \lstCoords;
\end{axis}
\end{tikzpicture}
\end{document}
可能更有用的变化是规范化步骤。
\documentclass[tikz,border=3mm]{standalone}
\usetikzlibrary{decorations.pathreplacing}
\tikzset{arrowed/.style={decorate,
decoration={show path construction,
moveto code={},
lineto code={
\draw[#1] (\tikzinputsegmentfirst) -- (\tikzinputsegmentlast);
},
curveto code={},
closepath code={},
}},arrowed/.default={-stealth}}
\usepackage{pgfplots}
\pgfplotsset{gradient function/.initial=f,
dx/.initial=0.01,dy/.initial=0.01}
\pgfmathdeclarefunction{xgrad}{2}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\edef\myfun{\pgfkeysvalueof{/pgfplots/gradient function}}%
\pgfmathparse{(\myfun(#1+\pgfkeysvalueof{/pgfplots/dx},#2)%
-\myfun(#1,#2))/\pgfkeysvalueof{/pgfplots/dx}}%
% \pgfmathsetmacro{\mysum}{\mysum+\myfun(\value{isum},#2)}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfmathdeclarefunction{ygrad}{2}{%
\begingroup%
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\edef\myfun{\pgfkeysvalueof{/pgfplots/gradient function}}%
\pgfmathparse{(\myfun(#1,#2+\pgfkeysvalueof{/pgfplots/dy})%
-\myfun(#1,#2))/\pgfkeysvalueof{/pgfplots/dy}}%
% \pgfmathsetmacro{\mysum}{\mysum+\myfun(\value{isum},#2)}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfplotsset{compat=1.17}
\begin{document}
\begin{tikzpicture}
\begin{axis}[width=12cm,%
declare function={f(\x,\y)=cos(deg(\x)*0.8)*cos(deg(\y)*0.6)*exp(0.1*\x);}]
\addplot3[surf,shader=interp,domain=-4:3,%samples=81
]{f(x,y)};
\edef\myx{1} % first x coordinate
\edef\myy{0.25} % first y coordinate
\edef\mystep{-0.25}% negative values mean descending
\pgfmathsetmacro{\myf}{f(\myx,\myy)}
\edef\lstCoords{(\myx,\myy,\myf)}
\pgfplotsforeachungrouped\X in{0,...,5}
{
\pgfmathsetmacro{\mydx}{xgrad(\myx,\myy)}
\pgfmathsetmacro{\mydy}{ygrad(\myx,\myy)}
\pgfmathsetmacro{\myscale}{\mystep/sqrt(\mydx*\mydx+\mydy*\mydy)}
\pgfmathsetmacro{\myx}{\myx+\myscale*\mydx}
\pgfmathsetmacro{\myy}{\myy+\myscale*\mydy}
\pgfmathsetmacro{\myf}{f(\myx,\myy)}
\edef\lstCoords{\lstCoords\space (\myx,\myy,\myf)}
}
\addplot3[samples y=0,arrowed] coordinates \lstCoords;
\end{axis}
\end{tikzpicture}
\end{document}
也可以使用quiver
情节。