我需要绘制3变量函数的水平曲面。变量位于列向量 X = [x,y,z] ^ t 中。函数是 f(X)= X ^ t * A * X 。其中 ^ t 表示转置, A 是3x3常量矩阵。我知道 A 是对称的,因此可对角化,即 A = V * D * V ^ t 。以防它变得有用。
我打算使用isosurface来获取等于某个级别的函数的点,然后使用patch来绘制。
但是我无法弄清楚如何为网格中的每个点计算函数的值。理想情况下我想做
x = linspace(-1, 1,10); y=x; z = x;
[XX,YY,ZZ]=meshgrid(x,y,z);
f = [XX YY ZZ]'*A*[XX YY ZZ];
level = 1;
s = isosurface(XX,YY,ZZ,f,level);
patch(s, 'EdgeColor','none','FaceColor','blue');
但由于XX和A的大小,这显然不会起作用。到目前为止,我所做的是自己做数学以获得XX,YY和ZZ的多项式函数,但它非常丑陋而不是实用。
有人知道怎么做吗?谢谢!
答案 0 :(得分:1)
如果我理解正确,这就是你想要的。在下面的解释中,我将使用示例中给出的10x10x10点(尽管代码适用于任意数量的点)。另外,我定义了一个随机的3x3矩阵A
。
一旦XX
,YY
和ZZ
生成为10x10x10阵列(步骤1),关键是构建一个1000x3矩阵,其中第一列是 x 坐标,第二个是 y ,第三个是 z 。这是下面代码中的变量XYZ
(步骤2)。
由于XYZ
是矩阵而不是向量,因此无法使用矩阵乘法计算函数f
。但是可以使用bsxfun
有效地获得它。首先计算一个中间1000x3x3变量(XYZ2
),其中包含1000个点中每个点的所有3x3坐标乘积(步骤3)。然后将其重新整形为1000x9矩阵,并乘以线性化A
得到的9x1向量(步骤4)。
如此获得的f
大小为1000x1。您需要将其重新整形为10x10x10阵列,以匹配XX
,YY
和ZZ
(步骤5)。然后,您可以根据代码使用isosurface
(步骤6)。
A = rand(3);
x = linspace(-1, 1,10); y = x; z = x;
[XX,YY,ZZ] = meshgrid(x,y,z); %// step 1
XYZ = [XX(:) YY(:) ZZ(:)]; %// step 2
XYZ2 = bsxfun(@times, XYZ, permute(XYZ, [1 3 2])); %// step 3
f = reshape(XYZ2,[],numel(A))*A(:); %// step 4
f = reshape(f, size(XX)); %// step 5
level = 1;
s = isosurface(XX,YY,ZZ,f,level);
patch(s, 'EdgeColor','none','FaceColor','blue'); %// step 6
答案 1 :(得分:-1)
我怀疑你可以明确地将你的功能定义为
ffun = @(x,y,z) [x y z]*A*[x; y; z];
然后使用arrayfun
将此函数应用于坐标向量的每个元素:
f = arrayfun(ffun,XX,YY,ZZ);
这将为f(i)=ffun(XX(i),YY(i),ZZ(i))
中的每个i
返回1:numel(XX)
,我认为这就是你所追求的。输出f
将具有与输入数组相同的形状,这似乎可以在以后与isosurface
一起使用。