在MATLAB中对球面的一个子集进行阴影处理

4
我正在尝试生成一个半球的图形,并在表面上用高程和方位角的最大/最小值限制的阴影区域进行填充。本质上,我正在尝试复制这个图像。生成半球是很容易的,但是之后我就被难住了。有什么想法吗?
这是我用来生成这个球体的代码:
[x,y,z] = sphere; 
x = x(11:end,:);
y = y(11:end,:); 
z = z(11:end,:);
r = 90; 
surf(r.*x,r.*y,r.*z,'FaceColor','yellow','FaceAlpha',0.5); 
axis equal;

请问你有一些用来生成半球的代码吗?根据你生成半球的方式,我们可以确定如何对其进行子集划分并相应地着色。 - rayryeng
当然,[x,y,z] = sphere; x = x(11:end,:);y = y(11:end,:);
z = z(11:end,:);
r = 90;
surf(r.*x,r.*y,r.*z,'FaceColor','yellow','FaceAlpha',0.5);
axis equal;
- Baconfish
在表面上呈现图案的一般方法可以在此处找到:http://stackoverflow.com/a/23900282/2777181 - Cape Code
我有一个答案可以帮助你使用方位角和俯仰角限制你的空间。请给我几分钟。 - rayryeng
2个回答

3
如果要突出半球的某个区域,首先确定最小和最大方位(水平扫描)和高度(垂直扫描)角度。然后将你的 x,y,z 坐标转换为球坐标系中相应的角度。这样做后,你可以根据这些角度对你的 x,y,z 坐标进行子集筛选。要从笛卡尔坐标系转换为球坐标系,需要执行以下操作:

来源:Wikipedia 其中,theta 是高度角,phi 是方位角,r 是球体半径。因为 sphere 会生成单位球体的坐标,所以 r=1。因此,要计算角度,我们只需执行以下操作:
theta = acosd(z);
phi = atan2d(y, x);

请注意,高度/ theta 限制为0到180度,而方位角/ phi 限制在-180到180度之间。因为您只创建了半个球体,所以高度应该从0到90度简单变化。还要注意,acosd 和atan2d 以度数 返回结果。现在我们已经在这里,您只需要选择要绘制的球体部分。例如,假设我们希望限制球体,使最小和最大方位角跨越-90到90度,而仅高程跨越0到45度。因此,让我们找到满足这些约束条件的那些 x,y,z 坐标,并确保将范围之外的任何内容设置为 NaN ,以便不在球体上绘制这些点。如下所示:
%// Change your ranges here
minAzimuth = -90;
maxAzimuth = 90;
minElevation = 0;
maxElevation = 45;

%// Compute angles - assuming that you have already run the code for sphere
%// [x,y,z] = sphere;
%// x = x(11:end,:);
%// y = y(11:end,:); 
%// z = z(11:end,:);
theta = acosd(z);
phi = atan2d(y, x);

%%%%%// Begin highlighting logic
ind = (phi >= minAzimuth & phi <= maxAzimuth) & ...
      (theta >= minElevation & theta <= maxElevation); % // Find those indices
x2 = x; y2 = y; z2 = z; %// Make a copy of the sphere co-ordinates
x2(~ind) = NaN; y2(~ind) = NaN; z2(~ind) = NaN; %// Set those out of bounds to NaN

%%%%%// Draw our original sphere and then the region we want on top
r = 90;
surf(r.*x,r.*y,r.*z,'FaceColor','white','FaceAlpha',0.5); %// Base sphere
hold on;
surf(r.*x2,r.*y2,r.*z2,'FaceColor','red'); %// Highlighted portion
axis equal;
view(40,40); %// Adjust viewing angle for better view

我得到的结果是:

在此输入图片描述

我将代码模块化,这样您只需要更改代码开头定义的四个变量,输出便会突出显示由这些最小和最大范围所限制的半球的所需部分。


希望这可以帮到您!


1
非常感谢,这是我开始尝试操作它的绝佳起点。 - Baconfish
@Baconfish - 我已经将代码更改为更模块化,因此您只需要更改代码的前四行和该部分球体应根据那些最小值和最大值范围进行突出显示。 - rayryeng

2

一种选项是创建一个数组,将你想要分配给每个点的相应颜色。

一个最简单的示例(使用三角函数将方位角和俯仰角转换为x、y和z上的逻辑条件):

c=(y>0).*(x>0).*(z>0.1).*(z<0.5);
c(c==0)=NaN;
surf(r.*x,r.*y,r.*z,c ,'FaceAlpha',0.5); axis equal;

使用以下代码:

ex. image

注意:这仅适用于网格的分辨率。(即表面的每个“补丁”可以有不同的颜色)。为了精确地复制您的图,您可能希望将网格球与另一个具有更多网格点的球体叠加,并在其上应用上述代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接