Matlab - 使用surf和min函数减去两个3D图形

时间:2016-04-30 01:15:50

标签: matlab matlab-figure surf

我试图制作一个看起来像的冲浪地块:

enter image description here

到目前为止,我有:

x = [-1:1/100:1];
y = [-1:1/100:1];

[X,Y] = meshgrid(x,y);

Triangle1 = -abs(X) + 1.5;
Triangle2 = -abs(Y) + 1.5;

Z = min(Triangle1, Triangle2);

surf(X,Y,Z);
shading flat
colormap winter;
hold on;

[X,Y,Z] = sphere();
Sphere = surf(X, Y, Z + 1.5 );% sphere with radius 1 centred at (0,0,1.5)
hold off;

此代码生成的图形如下所示:

enter image description here

  • 竖立方形底座([-1,1] x [-1,1])的金字塔和高于原点(0,0)的高度c = 1.5的顶点。

  • 通过去除位于以顶点为中心的半径为r = 1的球体内的金字塔顶部,挖空金字塔的顶部。

所以我需要保留金字塔内部球体表面的一部分并删除其余部分。请注意,每个图中的y轴是不同的,这就是为什么第二个图看起来有点浓缩的原因。是的,有一个金字塔进入球体,很难从这个角度看到。

我将使用70(方位角)和35(仰角)的视角。并确保轴正确缩放(如图所示)。在移除适当的球体表面后,我将使用AXIS TIGHT选项获得正确的尺寸。

2 个答案:

答案 0 :(得分:1)

这是我的拙见:

N = 400; % resolution
x = linspace(-1,1,N);
y = linspace(-1,1,N);
[X,Y] = meshgrid(x,y);
Triangle1 = -abs(X)+1.5 ;
Triangle2 = -abs(Y)+1.5 ;
Z = min(Triangle1, Triangle2);
Trig = alphaShape(X(:),Y(:),Z(:),2);
[Xs,Ys,Zs] = sphere(N-1);
Sphere = alphaShape(Xs(:),Ys(:),Zs(:)+2,2);
% get all the points from the pyramid that are within the sphere:
inSphere = inShape(Sphere,X(:),Y(:),Z(:));
Zt = Z;
Zt(inSphere) = nan; % remove the points in the sphere
surf(X,Y,Zt)
shading interp
view(70,35)
axis tight

我使用alphaShape对象从金字塔中删除所有不需要的点,然后在没有它们的情况下绘制它们:

enter image description here

我知道,它并不完美,因为你没有看到金字塔内圆圈的底部,但我所有尝试实现这一点的尝试都失败了。我的基本想法就是把它们拼凑在一起:

hold on;
Zc = Zs;
inTrig = inShape(Trig,Xs(:),Ys(:),Zs(:)+1.5);
Zc(~inTrig) = nan;
surf(Xs,Ys,Zc+1.5)
hold off

但结果不太好,因为你无法真正看到金字塔内的圆圈。

无论如何,我在这里发布,因为它可能会给你一个指导工作。

答案 1 :(得分:1)

EBH方法的替代方案。

在MATLAB中,从3d中减去两个形状的一般算法很难。相反,如果您记得半径为r的球体的等式为(x0,y0,z0),则为

r^2 = (x-x0)^2 + (y-y0)^2 + (z-z0)^2

然后求解z会给z = z0 +/- sqrt(r^2-(x-x0)^2-(y-y0)^2),其中在平方根前面使用+给出球体的顶部,-给出底部。在这种情况下,我们只对球体的底部感兴趣。为了获得最终表面,我们只需在金字塔和半球之间取最小值z

请注意,半球的域由实心圆r^2-(x-x0)^2-(y-y0)^2 >= 0定义。我们将域外的任何术语定义为无穷大,以便在采用最小值时忽略它们。

N = 400; % resolution
z0 = 1.5;  % sphere z offset
r = 1;     % sphere radius
x = linspace(-1,1,N);
y = linspace(-1,1,N);
[X,Y] = meshgrid(x,y);
% pyramid
Triangle1 = -abs(X)+1.5 ;
Triangle2 = -abs(Y)+1.5 ;
Pyramid = min(Triangle1, Triangle2);    
% half-sphere (hemisphere)
sqrt_term = r^2 - X.^2 - Y.^2;
HalfSphere = -sqrt(sqrt_term) + z0;
HalfSphere(sqrt_term < 0) = inf;
Z = min(HalfSphere, Pyramid);
surf(X,Y,Z)
shading interp
view(70,35)
axis tight

enter image description here