构建三元网格,在网格上计算函数,并在Matlab中绘制等高线图

构建三元网格,在网格上计算函数,并在Matlab中绘制等高线图,matlab,contour,ternary,ternplot,Matlab,Contour,Ternary,Ternplot,我需要评估一个函数(比如) Fxy=2*x.^2+3*y.^2; 在三元网格上,x范围(0-1)、y范围(0-1)和1-x-y(0-1)。 我无法构建需要评估上述函数的三元网格。此外,一旦评估,我需要在三元等高线图中绘制函数。理想情况下,我需要轴按逆时针方向运动(x->y-->(1-x-y)) 我已经试过这个功能了 function tg = triangle_grid ( n, t ) ng = ( ( n + 1 ) * ( n + 2 ) ) / 2; tg = zeros (

我需要评估一个函数(比如) Fxy=2*x.^2+3*y.^2; 在三元网格上,x范围(0-1)、y范围(0-1)和1-x-y(0-1)。 我无法构建需要评估上述函数的三元网格。此外,一旦评估,我需要在三元等高线图中绘制函数。理想情况下,我需要轴按逆时针方向运动(x->y-->(1-x-y))

我已经试过这个功能了

function tg = triangle_grid ( n, t )

  ng = ( ( n + 1 ) * ( n + 2 ) ) / 2;
  tg = zeros ( 2, ng );

  p = 0;

  for i = 0 : n
    for j = 0 : n - i
      k = n - i - j;
      p = p + 1;
      tg(1:2,p) = ( i * t(1:2,1) + j * t(1:2,2) + k * t(1:2,3) ) / n;
    end
  end

  return
end
三角形边坐标之间的子间隔数

n = 10 (say)
对于等边三角形的边坐标

t = tcoord = [0.0, 0.5,           1.0;
              0.0, 1.0*sqrt(3)/2, 0.0];
这将生成一个三角形网格,x轴从0-1开始,但其他两个不是从0-1开始

我需要这样的东西:

。。。轴范围为0-1(0-100也可以)

此外,我需要知道三角形网格内所有交点的坐标点。一旦我有了这个,我就可以继续在这个网格中计算函数了

我的最终目标是得到这样的东西。这更好地体现了我需要实现的目标(与我现在删除的上一个情节相比)

请注意,两个三元图的等值线大小不同。在我的例子中,差异是一个数量级,两个非常不同的Fxy

如果我能将两个三元图相互叠加,然后在三元平面上两个等值线的交点处计算成分。构图应为三元图,而不是定义三角形的矩形网格。
目前存在一些问题(如评论部分中强调的,一旦问题接近解决方案,将更新此内容)

我对文件交换提交进行了一些处理

如果您只是这样做:

[x,y]=meshgrid(0:0.1:1);
Fxy = 2*x.^2 +3 *y.^2;
ternpcolor(x(:),y(:),Fxy(:))
你会得到:


ternpcolor
函数中,三分之一轴完全按照您所说的(1-x-y)创建。这里有很多东西需要“调整”,但我希望它足以让您开始。

我已经对文件交换提交进行了一些调整

如果您只是这样做:

[x,y]=meshgrid(0:0.1:1);
Fxy = 2*x.^2 +3 *y.^2;
ternpcolor(x(:),y(:),Fxy(:))
你会得到:

ternpcolor
函数中,三分之一轴完全按照您所说的(1-x-y)创建。这里有很多东西需要“调整”,但我希望它足以让你开始。

我是《我的爱》的作者。正如您正确推测的那样,
ternpcolor
并不能满足您的需要,因为它是自动构建为网格数据的。回想起来,这不是一个特别明智的决定,我必须改变设计。同时,此代码应该执行您想要的操作:

编辑:我修改了代码以查找两条曲线的交点,而不是一条曲线

N = 10;
x = linspace(0, 1, N);
y = x;

% The grid intersections on your diagram are actually rectangularly arranged,
% so meshgrid will build the intersections for us
[xx, yy] = meshgrid(x, y);
zz = 1 - (xx + yy);

% now that we've got the intersections, we can evaluate the function
f1 = @(x, y) 2*x.^2 + 3*y.^2 + 0.1;
Fxy1 = f1(xx, yy);
Fxy1(xx + yy > 1) = nan;

f2 = @(x, y) 3*x.^2 + 2*y.^2;
Fxy2 = f2(xx, yy);
Fxy2(xx + yy > 1) = nan;

f3 = @(x, y) (3*x.^2 + 2*y.^2) * 1000; % different order of magnitude
Fxy3 = f3(xx, yy);
Fxy3(xx + yy > 1) = nan;

subplot(1, 2, 1)
% This constructs the ternary axes
ternaxes(5);

% These are the coordinates of the compositions mapped to plot coordinates
[xg, yg] = terncoords(xx, yy);
% simpletri constructs the correct triangles
tri = simpletri(N);

hold on
% and now we can plot
trisurf(tri, xg, yg, Fxy1);
trisurf(tri, xg, yg, Fxy2);
hold off
view([137.5, 30]);

subplot(1, 2, 2);
ternaxes(5)
% Here we plot the line of intersection of the two functions
contour(xg, yg, Fxy1 - Fxy2, [0 0], 'r')
axis equal

编辑2:如果要找到两条等高线之间的交点,可以有效地求解两个联立方程组。这段额外的代码将为您解决这个问题(请注意,我在上面的代码中也使用了一些匿名函数):

我是这本书的作者。正如您正确推测的那样,
ternpcolor
并不能满足您的需要,因为它是自动构建为网格数据的。回想起来,这不是一个特别明智的决定,我必须改变设计。同时,此代码应该执行您想要的操作:

编辑:我修改了代码以查找两条曲线的交点,而不是一条曲线

N = 10;
x = linspace(0, 1, N);
y = x;

% The grid intersections on your diagram are actually rectangularly arranged,
% so meshgrid will build the intersections for us
[xx, yy] = meshgrid(x, y);
zz = 1 - (xx + yy);

% now that we've got the intersections, we can evaluate the function
f1 = @(x, y) 2*x.^2 + 3*y.^2 + 0.1;
Fxy1 = f1(xx, yy);
Fxy1(xx + yy > 1) = nan;

f2 = @(x, y) 3*x.^2 + 2*y.^2;
Fxy2 = f2(xx, yy);
Fxy2(xx + yy > 1) = nan;

f3 = @(x, y) (3*x.^2 + 2*y.^2) * 1000; % different order of magnitude
Fxy3 = f3(xx, yy);
Fxy3(xx + yy > 1) = nan;

subplot(1, 2, 1)
% This constructs the ternary axes
ternaxes(5);

% These are the coordinates of the compositions mapped to plot coordinates
[xg, yg] = terncoords(xx, yy);
% simpletri constructs the correct triangles
tri = simpletri(N);

hold on
% and now we can plot
trisurf(tri, xg, yg, Fxy1);
trisurf(tri, xg, yg, Fxy2);
hold off
view([137.5, 30]);

subplot(1, 2, 2);
ternaxes(5)
% Here we plot the line of intersection of the two functions
contour(xg, yg, Fxy1 - Fxy2, [0 0], 'r')
axis equal

编辑2:如果要找到两条等高线之间的交点,可以有效地求解两个联立方程组。这段额外的代码将为您解决这个问题(请注意,我在上面的代码中也使用了一些匿名函数):


这是一个使用R和我的软件包的解决方案。为了便于比较,我还将附近的点包括在下面

library(ggtern)

Fxy      = function(x,y){ 2*x^2 + 3*y^2 }
x = y    = seq(0,1,length.out = 100)
df       = expand.grid(x=x,y=y); 
df$z     = 1 - df$x - df$y
df       = subset(df,z >= 0)
df$value = Fxy(df$x,df$y)

#The Intended Breaks
breaks = pretty(df$value,n=10)

#Create subset of the data, within close proximity to the breaks
df.sub = ldply(breaks,function(b,proximity = 0.02){
  s = b - abs(proximity)/2; f = b + abs(proximity)/2
  subset(df,value >= s & value <= f)
})

#Plot the ternary diagram
ggtern(df,aes(x,y,z)) + 
  theme_bw() + 
  geom_point(data=df.sub,alpha=0.5,color='red',shape=21) + 
  geom_interpolate_tern(aes(value = value,color=..level..), size = 1, n = 200,
                        breaks    = c(breaks,max(df$value) - 0.01,min(df$value) + 0.01),
                        base      = 'identity',
                        formula   = value ~ poly(x,y,degree=2)) +
  labs(title = "Contour Plot on Modelled Surface", x = "Left",y="Top",z="Right")
库(ggtern)
Fxy=函数(x,y){2*x^2+3*y^2}
x=y=seq(0,1,长度=100)
df=expand.grid(x=x,y=y);
df$z=1-df$x-df$y
df=子集(df,z>=0)
df$value=Fxy(df$x,df$y)
#预定的休息时间
断开=漂亮(df$值,n=10)
#在靠近断点的位置创建数据子集
df.sub=ldply(断开,功能(b,接近度=0.02){
s=b-abs(接近)/2;f=b+abs(接近)/2

子集(df,value>=s&value这是一个使用R和我的包的解决方案。为了比较,我还包括了下面的邻近点

library(ggtern)

Fxy      = function(x,y){ 2*x^2 + 3*y^2 }
x = y    = seq(0,1,length.out = 100)
df       = expand.grid(x=x,y=y); 
df$z     = 1 - df$x - df$y
df       = subset(df,z >= 0)
df$value = Fxy(df$x,df$y)

#The Intended Breaks
breaks = pretty(df$value,n=10)

#Create subset of the data, within close proximity to the breaks
df.sub = ldply(breaks,function(b,proximity = 0.02){
  s = b - abs(proximity)/2; f = b + abs(proximity)/2
  subset(df,value >= s & value <= f)
})

#Plot the ternary diagram
ggtern(df,aes(x,y,z)) + 
  theme_bw() + 
  geom_point(data=df.sub,alpha=0.5,color='red',shape=21) + 
  geom_interpolate_tern(aes(value = value,color=..level..), size = 1, n = 200,
                        breaks    = c(breaks,max(df$value) - 0.01,min(df$value) + 0.01),
                        base      = 'identity',
                        formula   = value ~ poly(x,y,degree=2)) +
  labs(title = "Contour Plot on Modelled Surface", x = "Left",y="Top",z="Right")
库(ggtern)
Fxy=函数(x,y){2*x^2+3*y^2}
x=y=seq(0,1,长度=100)
df=expand.grid(x=x,y=y);
df$z=1-df$x-df$y
df=子集(df,z>=0)
df$value=Fxy(df$x,df$y)
#预定的休息时间
断开=漂亮(df$值,n=10)
#在靠近断点的位置创建数据子集
df.sub=ldply(断开,功能(b,接近度=0.02){
s=b-abs(接近)/2;f=b+abs(接近)/2

子集(df,value>=s&value是的,但据我所知,它使用测量数据。我需要根据函数生成数据。哦,我明白了。你不需要三元绘图。你只需要在1-x-y在范围(0-1)内的区域绘图,对吗?我确实想要一个三元图,但我需要先在三角形网格上生成数据。就我所知,我需要先生成三角形网格,然后在上面计算函数Fxy。一旦生成了数据,我需要在三元conout图中绘制数据。请原谅我的无知,但三元图不是一个用3个变量绘图?你只有2个。当然,如果你用你的条件裁剪2D网格,结果将是一个三角形,但不是三元绘图。是的,但据我所知,它使用测量数据。我需要根据函数生成数据。哦,我明白了。你不需要三元绘图。你只需要在1-x-y的区域绘图在(0-1)范围内,对吗?我确实想要一个三元图,但我需要先在三角形网格上生成数据。对于这个,作为fa