\pgfmathdeclarefunction 中的函数内函数

\pgfmathdeclarefunction 中的函数内函数

我正在尝试绘制一个复杂函数,为此我使用了pgfmathdeclarefunction。但是,我无法让它工作,我得到了错误:

! \pgfmathNi@ 定义中的参数数量非法。

我开始怀疑我试图做的事情是否可行:在 的定义中调用另一个函数中的函数pgfmathdeclarefunction。这是 MWE:

\documentclass{standalone}

\usepackage{pgfplots}

\pgfmathdeclarefunction{detG}{8}{%
  \pgfmathparse{#1*(#7*(#4 - #6)*(#2 - #8) - #5*(#2 - #6)*(#4 - #8) + #3*(#2 - #4)*(#6 - #8)) + #3*#5*(#4 - #6)*(#2 - #8) - #3*#7*(#2 - #6)*(#4 - #8) + #5*#7*(#2 - #4)*(#6 - #8)
  }%
}

\pgfmathdeclarefunction{Hii}{8}{%
  \pgfmathparse{#5*#7*#4*(#6 - #8) + #3*#5*(#4 - #6)*#8 + #3*#7*#6*(-#4 + #8)
  }%
}

\pgfmathdeclarefunction{Hji}{8}{%
  \pgfmathparse{#3*#4*(#6 - #8) + #7*(#4 - #6)*#8 + #5*#6*(-#4 + #8)
  }%
}

\pgfmathdeclarefunction{Hki}{8}{%
  \pgfmathparse{#3*#5*(-#4 + #6) + #3*#7*(#4 - #8) + #5*#7*(-#6 + #8)
  }%
}

\pgfmathdeclarefunction{Hli}{8}{%
  \pgfmathparse{#7*(-#4 + #6) + #5*(#4 - #8) + #3*(-#6 + #8)
  }%
}

\pgfmathdeclarefunction{Ni}{10}{%
  \pgfmathparse{Hii(#1,#2,#3,#4,#5,#6,#7,#8) + Hji(#1,#2,#3,#4,#5,#6,#7,#8)*#9 + Hki(#1,#2,#3,#4,#5,#6,#7,#8)*#10 + Hli(#1,#2,#3,#4,#5,#6,#7,#8)*#9*#10
  }%
}


\begin{document}

\begin{tikzpicture}[]
\begin{axis}[]

\addplot3[surf,domain=0:1, samples=20] { Ni(-1,-1,0,-1,0,0,-1,0,x,y) / detG(-1,-1,0,-1,0,0,-1,0)};

\end{axis}

\end{tikzpicture}

\end{document}

编辑 感谢 @Qrrbrbirlbel 提供的答案,我可以绘制一个函数。我设法将代码概括为绘制其中 4 个函数(非常相似)。这些函数应该构成一个帐篷,以便在其自己的方形域中绘制的每个函数在坐标 (0,0) 处的值均为 1。这是我目前得到的结果,虽然它可以工作,但有很多重复的代码:

4 个函数 Ni、Nj、Nk 和 Nl

和当前代码:

\documentclass[tikz]{standalone}
\usepackage{pgfplots}

\pgfmathdeclarefunction{detGi}{8}{%
  \pgfmathparse{-(#1*(#7*(#4-#6)*(#2-#8)-#5*(#2-#6)*(#4-#8)+#3*(#2-#4)*(#6-#8))
    +#3*#5*(#4-#6)*(#2-#8)-#3*#7*(#2-#6)*(#4-#8)+#5*#7*(#2-#4)*(#6-#8))}}

\pgfmathdeclarefunction{detGj}{8}{%
  \pgfmathparse{-(#1*(#7*(#4-#6)*(#2-#8)-#5*(#2-#6)*(#4-#8)+#3*(#2-#4)*(#6-#8))
    +#3*#5*(#4-#6)*(#2-#8)-#3*#7*(#2-#6)*(#4-#8)+#5*#7*(#2-#4)*(#6-#8))}}

\pgfmathdeclarefunction{detGk}{8}{%
  \pgfmathparse{-(#1*(#7*(#4-#6)*(#2-#8)-#5*(#2-#6)*(#4-#8)+#3*(#2-#4)*(#6-#8))
    +#3*#5*(#4-#6)*(#2-#8)-#3*#7*(#2-#6)*(#4-#8)+#5*#7*(#2-#4)*(#6-#8))}}

\pgfmathdeclarefunction{detGl}{8}{%
  \pgfmathparse{-(#1*(#7*(#4-#6)*(#2-#8)-#5*(#2-#6)*(#4-#8)+#3*(#2-#4)*(#6-#8))
    +#3*#5*(#4-#6)*(#2-#8)-#3*#7*(#2-#6)*(#4-#8)+#5*#7*(#2-#4)*(#6-#8))}}

\pgfmathdeclarefunction{Hii}{8}{%
  \pgfmathparse{#5*#7*#4*(#6-#8)+#3*#5*(#4-#6)*#8+#3*#7*#6*(-#4+#8)}}
\pgfmathdeclarefunction{Hji}{8}{%
  \pgfmathparse{#3*#4*(#6-#8)+#7*(#4-#6)*#8+#5*#6*(-#4+#8)}}
\pgfmathdeclarefunction{Hki}{8}{%
  \pgfmathparse{#3*#5*(-#4+#6)+#3*#7*(#4-#8)+#5*#7*(-#6+#8)}}
\pgfmathdeclarefunction{Hli}{8}{%
  \pgfmathparse{#7*(-#4+#6)+#5*(#4-#8)+#3*(-#6+#8)}}

\pgfmathdeclarefunction{Hij}{8}{%
  \pgfmathparse{#1*#7*#6*(#2-#8)+#1*#5*(-#2+#6)*#8+#5*#7*#2*(-#6+#8)}}
\pgfmathdeclarefunction{Hjj}{8}{%
  \pgfmathparse{#5*#6*(#2-#8)+#7*(-#2+#6)*#8+#1*#2*(-#6+#8)}}
\pgfmathdeclarefunction{Hkj}{8}{%
  \pgfmathparse{#1*#5*(#2-#6)+#5*#7*(#6-#8)+#1*#7*(-#2+#8)}}
\pgfmathdeclarefunction{Hlj}{8}{%
  \pgfmathparse{#7*(#2-#6)+#1*(#6-#8)+#5*(-#2+#8)}}

\pgfmathdeclarefunction{Hik}{8}{%
  \pgfmathparse{#3*#7*#2*(#4-#8)+#1*#3*(#2-#4)*#8+#1*#7*#4*(-#2+#8)}}
\pgfmathdeclarefunction{Hjk}{8}{%
  \pgfmathparse{#1*#2*(#4-#8)+#7*(#2-#4)*#8+#3*#4*(-#2+#8)}}
\pgfmathdeclarefunction{Hkk}{8}{%
  \pgfmathparse{#1*#3*(-#2+#4)+#1*#7*(#2-#8)+#3*#7*(-#4+#8)}}
\pgfmathdeclarefunction{Hlk}{8}{%
  \pgfmathparse{#7*(-#2+#4)+#3*(#2-#8)+#1*(-#4+#8)}}

\pgfmathdeclarefunction{Hil}{8}{%
  \pgfmathparse{#1*#5*#4*(#2-#6)+#1*#3*(-#2+#4)*#6+#3*#5*#2*(-#4+#6)}}
\pgfmathdeclarefunction{Hjl}{8}{%
  \pgfmathparse{#3*#4*(#2-#6)+#5*(-#2+#4)*#6+#1*#2*(-#4+#6)}}
\pgfmathdeclarefunction{Hkl}{8}{%
  \pgfmathparse{#1*#3*(#2-#4)+#3*#5*(#4-#6)+#1*#5*(-#2+#6)}}
\pgfmathdeclarefunction{Hll}{8}{%
  \pgfmathparse{#5*(#2-#4)+#1*(#4-#6)+#3*(-#2+#6)}}



\makeatletter
\pgfmathdeclarefunction{Ni}{2}{%
  \begingroup
    \def\vo##1{\pgfkeysvalueof{/pgfplots/helper/##1}}% shortcut for here
    \pgfmathparse{\vo{Hii}+\vo{Hji}*#1+\vo{Hki}*#2+\vo{Hli}*#1*#2}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\pgfmathdeclarefunction{NiDet}{2}{%
  \begingroup
    \pgfmathNi@{#1}{#2}%
    \pgfmathdivide@{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/helper/detGi}}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}

\pgfmathdeclarefunction{Nj}{2}{%
  \begingroup
    \def\vo##1{\pgfkeysvalueof{/pgfplots/helper/##1}}% shortcut for here
    \pgfmathparse{\vo{Hij}+\vo{Hjj}*#1+\vo{Hkj}*#2+\vo{Hlj}*#1*#2}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\pgfmathdeclarefunction{NjDet}{2}{%
  \begingroup
    \pgfmathNj@{#1}{#2}%
    \pgfmathdivide@{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/helper/detGj}}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}

\pgfmathdeclarefunction{Nk}{2}{%
  \begingroup
    \def\vo##1{\pgfkeysvalueof{/pgfplots/helper/##1}}% shortcut for here
    \pgfmathparse{\vo{Hik}+\vo{Hjk}*#1+\vo{Hkk}*#2+\vo{Hlk}*#1*#2}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\pgfmathdeclarefunction{NkDet}{2}{%
  \begingroup
    \pgfmathNk@{#1}{#2}%
    \pgfmathdivide@{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/helper/detGk}}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}

\pgfmathdeclarefunction{Nl}{2}{%
  \begingroup
    \def\vo##1{\pgfkeysvalueof{/pgfplots/helper/##1}}% shortcut for here
    \pgfmathparse{\vo{Hil}+\vo{Hjl}*#1+\vo{Hkl}*#2+\vo{Hll}*#1*#2}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\pgfmathdeclarefunction{NlDet}{2}{%
  \begingroup
    \pgfmathNl@{#1}{#2}%
    \pgfmathdivide@{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/helper/detGl}}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}

\pgfkeys{
  /handlers/.pgfmath/.code=%
    \pgfmathparse{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult},
  /handlers/.pgfmath fpu/.code=%
    \begingroup\pgfset{fpu}\pgfmathparse{#1}\expandafter\endgroup
    \expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\makeatother

\begin{document}
\begin{tikzpicture}
\begin{axis}

% plot Nj in [-1,0]x[0,1]
\pgfplotsset{
  helper/Hij/.initial=0,  helper/Hjj/.initial=0,
  helper/Hkj/.initial=0,  helper/Hlj/.initial=0,
  helper/detGj/.initial=0,
  prepare matrix/.style={
    helper/Hij/.pgfmath fpu={Hij(#1)}, helper/Hjj/.pgfmath fpu={Hjj(#1)},
    helper/Hkj/.pgfmath fpu={Hkj(#1)}, helper/Hlj/.pgfmath fpu={Hlj(#1)},
    helper/detGj/.pgfmath fpu={detGj(#1)}
    }}
  
\addplot3[surf, domain=-1:0, y domain=0:1, samples=20, prepare matrix={-1,0,0,0,0,1,-1,1}]
  {NjDet(x,y)};
  
% plot Ni in [0,1]x[0,1]
\pgfplotsset{
  helper/Hii/.initial=0,  helper/Hji/.initial=0,
  helper/Hki/.initial=0,  helper/Hli/.initial=0,
  helper/detGi/.initial=0,
  prepare matrix/.style={
    helper/Hii/.pgfmath fpu={Hii(#1)}, helper/Hji/.pgfmath fpu={Hji(#1)},
    helper/Hki/.pgfmath fpu={Hki(#1)}, helper/Hli/.pgfmath fpu={Hli(#1)},
    helper/detGi/.pgfmath fpu={detGi(#1)}
    }}
  
\addplot3[surf, domain=0:1, y domain=0:1, samples=20, prepare matrix={0,0,1,0,1,1,0,1}]
  {NiDet(x,y)};
  
  
% plot Nk in [-1,0]x[-1,0]
\pgfplotsset{
  helper/Hik/.initial=0,  helper/Hjk/.initial=0,
  helper/Hkk/.initial=0,  helper/Hlk/.initial=0,
  helper/detGk/.initial=0,
  prepare matrix/.style={
    helper/Hik/.pgfmath fpu={Hik(#1)}, helper/Hjk/.pgfmath fpu={Hjk(#1)},
    helper/Hkk/.pgfmath fpu={Hkk(#1)}, helper/Hlk/.pgfmath fpu={Hlk(#1)},
    helper/detGk/.pgfmath fpu={detGk(#1)}
    }}

\addplot3[surf, domain=-1:0, y domain=-1:0, samples=20, prepare matrix={-1,-1,0,-1,0,0,-1,0}]
  {NkDet(x,y)};
  
% plot Nl in [0,1]x[-1,0]
\pgfplotsset{
  helper/Hil/.initial=0,  helper/Hjl/.initial=0,
  helper/Hkl/.initial=0,  helper/Hll/.initial=0,
  helper/detGl/.initial=0,
  prepare matrix/.style={
    helper/Hil/.pgfmath fpu={Hil(#1)}, helper/Hjl/.pgfmath fpu={Hjl(#1)},
    helper/Hkl/.pgfmath fpu={Hkl(#1)}, helper/Hll/.pgfmath fpu={Hll(#1)},
    helper/detGl/.pgfmath fpu={detGl(#1)}
    }}
  
\addplot3[surf, domain=0:1, y domain=-1:0, samples=20, prepare matrix={0,-1,1,-1,1,0,0,0}]
  {NlDet(x,y)};

  
\end{axis}
\end{tikzpicture}
\end{document}

答案1

#10(这是 TeX 的限制),PGF手册指出

对于具有超过九个参数的函数,或者具有可变数量参数的函数,这些宏仅定义为采用参数。公共宏要求其参数以逗号分隔,例如\pgfmathVariableArgs{1.1,3.5,-1.5,2.6}。每个参数都按如下方式解析并传递给私有宏:\pgfmathVariableArgs@{{1.1}{3.5}{-1.5}{2.6}}。这意味着需要进行一些“额外工作”才能访问每个参数(尽管这是一项相当简单的任务)。

转换确实不太难。为了方便起见,我改变了参数的顺序,现在它们是Ni(x,y,…)

\makeatletter
\pgfmathdeclarefunction{Ni}{10}{%
  \begingroup
%      \typeout{Input: -#1-}%
      % get the last eight arguments
      \edef\pgfmath@temp{\pgfmath@util@lasteight#1\relax}%
      % and use them with Hii
      \expandafter\pgfmathHii@\pgfmath@temp
      % and save their result
      \let\pgfmath@Hii\pgfmathresult
      % and Hji
      \expandafter\pgfmathHji@\pgfmath@temp
      \let\pgfmath@Hji\pgfmathresult
      % and Hki
      \expandafter\pgfmathHki@\pgfmath@temp
      \let\pgfmath@Hki\pgfmathresult
      % and Hli
      \expandafter\pgfmathHli@\pgfmath@temp
      \let\pgfmath@Hli\pgfmathresult
      %
      % get the first (x)
      \edef\pgfmath@temp{\pgfmath@util@firstofmany#1\relax}%
      % multiply it with Hji
      \pgfmathmultiply@{\pgfmath@temp}{\pgfmath@Hji}%
      \let\pgfmath@Hji\pgfmathresult
      % and Hli
      \pgfmathmultiply@{\pgfmath@temp}{\pgfmath@Hli}%
      \let\pgfmath@Hli\pgfmathresult
      %
      % get the second (y)
      \edef\pgfmath@temp{\pgfmath@util@secondofmany#1\relax}%
      % multiply it with Hki
      \pgfmathmultiply@{\pgfmath@temp}{\pgfmath@Hki}%
      \let\pgfmath@Hki\pgfmathresult
      % and also with Hli (which was already multiplied with the first)
      \pgfmathmultiply@{\pgfmath@temp}{\pgfmath@Hli}%
      \let\pgfmath@Hli\pgfmathresult
      %
      % add it all together (\pgfmathadd@ ...)
      \pgfmathparse{\pgfmath@Hii+\pgfmath@Hji+\pgfmath@Hki+\pgfmath@Hli}%
%      \typeout{Result: \pgfmathresult}%
      \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\def\pgfmath@util@lasteight#1#2#3\relax{#3}%
\def\pgfmath@util@firstofmany#1#2\relax{#1}%
\def\pgfmath@util@secondofmany#1#2#3\relax{#2}%
\makeatother

基本上,我们使用三个返回的辅助宏

  • 除前两个之外
  • 仅第一个 ( x) 或
  • 仅第二个(y

参数。由于在第一种情况下,我们的参数形式为 ,因此{1}{2}{3}{…}{8}我们应该直接将它们与\pgfmathHii或一起使用\pgfmathHii@,而不能使用\pgfmathparse。该函数的其余部分只是乘法和加法。

然后我们可以这样使用它:

\addplot3[surf, domain=-1:1, y domain=-1:1, samples=41]
  {Ni(abs(x),abs(y),0,0,1,0,1,1,0,1)/det(0,0,1,0,1,1,0,1)};

话虽如此,我认为使用预先计算的值的以下方法更好,它肯定更快(因素 3)。


无论哪种方式,由于这些值中的大多数都是固定的并且不依赖于xy我会通过使用双参数函数Nxy(x,y)(后来NxyDet(x,y)包括det因子)来规避这个问题,该函数使用存储在一些值键中的值。

此外,我不会存储所有其他八个参数,而是会预先计算固定部分(因为detfactorfactorxfactory都不factorxy依赖于xy)。

为了更容易地评估和存储值键中的返回值,我使用了一个特殊的键处理程序.pgfmath- 或者更确切地说,.pgfmath fpu因为 PGFPlotsfpu在内部使用 - 它评估给定的值并将结果返回给键。

该函数Nxy仅使用这四个值,并根据原始函数添加这些值

Nxy(x, y) = factor + factorx * x + factory * y + factorxy * x * y

在我定义的内部Nxy,定义了一个快捷宏,\pgfkeysvalueof由于它仅在组内部定义,因此该函数定义将无法继续存在。

由于因子det也是固定的且不依赖于xy,我还将提供一个NxyDet使用我们自己的自定义Nxy函数的函数,并将其返回值除以预先计算的det值。


当你将创建两个宏\pgfdeclare时:function{<name>}

  1. \pgfmath<name>
  2. \pgfmath<name>@

第一个是公共接口,我们可以在其中使用任何其他 PGFmath 表达式,例如\pgfmathNxy{1+2}{17/2*sqrt(2)},它将被评估像往常一样由 PGFmath 解析(与相比只是节省了解析步骤\pgfmathparse{Nxy(1+2, 17/2*sqrt(2))})。

第二个版本仅接受已评估的参数(并由 内部使用\pgfmath<name>)。在 的主体中,\pgfdeclarefunction我们实际上定义了第二个版本,它将由第一个版本的 PGFMath 包装,我们可以预期#1#2已经被解析和评估,并且仅包含一个值。

因此,我们可以直接使用\pgfmathNxy@NxyDet节省另一个解析步骤。

我们也可以这样写

\pgfmathparse{Nxy(#1,#2)/\pgfkeysvalueof{/pgfplots/helper/det}}

这样也可以。


我们本.pgfmath fpu可以使用

prepare matrix/.style={
  /utils/exec=\pgfset{fpu}\pgfmathparse{Hii(#1)},
  helper/Hii/.expanded=\pgfmathresult,
  /utils/exec=\pgfmathparse{Hji(#1)},
  helper/Hji/.expanded=\pgfmathresult,
  /utils/exec=\pgfmathparse{Hki(#1)},
  helper/Hki/.expanded=\pgfmathresult,
  /utils/exec=\pgfmathparse{Hli(#1)},
  helper/Hli/.expanded=\pgfmathresult,
  /utils/exec=\pgfmathparse{detG(#1)}\pgfset{fpu=false},
  helper/detG/.expanded=\pgfmathresult,
}

或以任何其他方式计算五个值并将它们存储在类似的地方

prepare matrix/.code={
  \pgfset{fpu}%
  \pgfmathsetmacro\myHii{Hii(#1)}%
  \pgfmathsetmacro\myHji{Hji(#1)}%
  \pgfmathsetmacro\myHki{Hki(#1)}%
  \pgfmathsetmacro\myHli{Hli(#1)}%
  \pgfmathsetmacro\mydetG{detG(#1)}%
  \pgfset{fpu=false}%
}

然后只需使用这些宏,但在我看来,PGFkeys 使其变得非常简单,然后我们已经有了适当的命名空间宏/键。

代码

\documentclass[tikz]{standalone}
\usepackage{pgfplots}
\pgfmathdeclarefunction{det}{8}{%
  \pgfmathparse{-(#1*(#7*(#4-#6)*(#2-#8)-#5*(#2-#6)*(#4-#8)+#3*(#2-#4)*(#6-#8))
    +#3*#5*(#4-#6)*(#2-#8)-#3*#7*(#2-#6)*(#4-#8)+#5*#7*(#2-#4)*(#6-#8))}}
\pgfmathdeclarefunction{Hii}{8}{\pgfmathparse{#5*#7*#4*(#6-#8)+#3*#5*( #4-#6)*#8+#3*#7*#6*(-#4+#8)}}
\pgfmathdeclarefunction{Hij}{8}{\pgfmathparse{#1*#7*#6*(#2-#8)+#1*#5*(-#2+#6)*#8+#5*#7*#2*(-#6+#8)}}
\pgfmathdeclarefunction{Hik}{8}{\pgfmathparse{#3*#7*#2*(#4-#8)+#1*#3*( #2-#4)*#8+#1*#7*#4*(-#2+#8)}}
\pgfmathdeclarefunction{Hil}{8}{\pgfmathparse{#1*#5*#4*(#2-#6)+#1*#3*(-#2+#4)*#6+#3*#5*#2*(-#4+#6)}}

\pgfmathdeclarefunction{Hji}{8}{\pgfmathparse{#3*#4*(#6-#8)+#7*( #4-#6)*#8+#5*#6*(-#4+#8)}}
\pgfmathdeclarefunction{Hjj}{8}{\pgfmathparse{#5*#6*(#2-#8)+#7*(-#2+#6)*#8+#1*#2*(-#6+#8)}}
\pgfmathdeclarefunction{Hjk}{8}{\pgfmathparse{#1*#2*(#4-#8)+#7*( #2-#4)*#8+#3*#4*(-#2+#8)}}
\pgfmathdeclarefunction{Hjl}{8}{\pgfmathparse{#3*#4*(#2-#6)+#5*(-#2+#4)*#6+#1*#2*(-#4+#6)}}

\pgfmathdeclarefunction{Hki}{8}{\pgfmathparse{#3*#5*(-#4+#6)+#3*#7*(#4-#8)+#5*#7*(-#6+#8)}}
\pgfmathdeclarefunction{Hkj}{8}{\pgfmathparse{#1*#5*( #2-#6)+#5*#7*(#6-#8)+#1*#7*(-#2+#8)}}
\pgfmathdeclarefunction{Hkk}{8}{\pgfmathparse{#1*#3*(-#2+#4)+#1*#7*(#2-#8)+#3*#7*(-#4+#8)}}
\pgfmathdeclarefunction{Hkl}{8}{\pgfmathparse{#1*#3*( #2-#4)+#3*#5*(#4-#6)+#1*#5*(-#2+#6)}}

\pgfmathdeclarefunction{Hli}{8}{\pgfmathparse{#7*(-#4+#6)+#5*(#4-#8)+#3*(-#6+#8)}}
\pgfmathdeclarefunction{Hlj}{8}{\pgfmathparse{#7*( #2-#6)+#1*(#6-#8)+#5*(-#2+#8)}}
\pgfmathdeclarefunction{Hlk}{8}{\pgfmathparse{#7*(-#2+#4)+#3*(#2-#8)+#1*(-#4+#8)}}
\pgfmathdeclarefunction{Hll}{8}{\pgfmathparse{#5*( #2-#4)+#1*(#4-#6)+#3*(-#2+#6)}}

\makeatletter
\pgfmathdeclarefunction{Nxy}{2}{%
  \begingroup
    \def\vo##1{\pgfkeysvalueof{/pgfplots/helper/##1}}% shortcut for here
    \pgfmathparse{\vo{factor}+\vo{factorx}*#1+\vo{factory}*#2+\vo{factorxy}*#1*#2}%
    \pgfmathsmuggle\pgfmathresult
  \endgroup
}
\pgfmathdeclarefunction{NxyDet}{2}{%
  % quicker than \pgfmathparse{Nxy(#1,#2)/\pgfkeysvalueof{/pgfplots/helper/det}}
  \pgfmathNxy@{#1}{#2}%
  \pgfmathdivide@{\pgfmathresult}{\pgfkeysvalueof{/pgfplots/helper/det}}%
}

\pgfkeys{
  /handlers/.pgfmath/.code=%
    \pgfmathparse{#1}\expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult},
  /handlers/.pgfmath fpu/.code=%
    \begingroup\pgfset{fpu}\pgfmathparse{#1}\expandafter\endgroup
    \expandafter\pgfkeys@exp@call\expandafter{\pgfmathresult}}
\makeatother
\pgfplotsset{
  helper/factor/.initial=0,
  helper/factorx/.initial=0,
  helper/factory/.initial=0,
  helper/factorxy/.initial=0,
  helper/det/.initial=0,
  prepare matrix/.style 2 args={
    helper/factor/.pgfmath fpu  ={Hi#1(#2)}, 
    helper/factorx/.pgfmath fpu ={Hj#1(#2)},
    helper/factory/.pgfmath fpu ={Hk#1(#2)},
    helper/factorxy/.pgfmath fpu={Hl#1(#2)},
    helper/det/.pgfmath fpu     ={det(#2)}}}
\begin{document}
\begin{tikzpicture}
\begin{axis}[every axis plot/.append style={surf, samples=20}]
\addplot3[domain=0:1, y domain=0:1,
  prepare matrix={i}{ 0, 0, 1, 0, 1, 1, 0, 1}] {NxyDet(x,y)};
\addplot3[domain=-1:0, y domain=0:1,
  prepare matrix={j}{-1, 0, 0, 0, 0, 1,-1, 1}] {NxyDet(x,y)};
\addplot3[domain=-1:0, y domain=-1:0,
  prepare matrix={k}{-1,-1, 0,-1, 0, 0,-1, 0}] {NxyDet(x,y)};
\addplot3[domain=0:1, y domain=-1:0,
  prepare matrix={l}{ 0,-1, 1,-1, 1, 0, 0, 0}] {NxyDet(x,y)};
\end{axis}
\end{tikzpicture}
\end{document}

输出

在此处输入图片描述

相关内容