我试图制作一个看起来像的冲浪地块:
到目前为止,我有:
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;
此代码生成的图形如下所示:
竖立方形底座([-1,1] x [-1,1])的金字塔和高于原点(0,0)的高度c = 1.5的顶点。
通过去除位于以顶点为中心的半径为r = 1的球体内的金字塔顶部,挖空金字塔的顶部。
所以我需要保留金字塔内部球体表面的一部分并删除其余部分。请注意,每个图中的y轴是不同的,这就是为什么第二个图看起来有点浓缩的原因。是的,有一个金字塔进入球体,很难从这个角度看到。
我将使用70(方位角)和35(仰角)的视角。并确保轴正确缩放(如图所示)。在移除适当的球体表面后,我将使用AXIS TIGHT选项获得正确的尺寸。
答案 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
对象从金字塔中删除所有不需要的点,然后在没有它们的情况下绘制它们:
我知道,它并不完美,因为你没有看到金字塔内圆圈的底部,但我所有尝试实现这一点的尝试都失败了。我的基本想法就是把它们拼凑在一起:
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