首页 > 解决方案 > Matlab - 如何填充 3D 空间中的区域?

问题描述

我想使用某些条件填充 3D 空间中的一个区域。

假设有这样一个向量:

x1 = 100;
y1 = 102;
z1 = 103;
P1 = [x1, y1, z1];

现在我想指出所有可能值的空间,P2 = [x2, y2, z2];例如:

x2 < x1;
y2 < y1;
z2 < z1;
x1 - x2 < y1 - y2;
y1 - y2 < z1 - z2;
|angle between P1 and P2| < pi/20

我不认为fill3函数会起作用。

我尝试绘制所有可能的点,但速度很慢:

r1 = 100;
g1 = 102;
b1 = 103;

P1 = [r1, g1, b1];

for r2 = 0:0.1:r1
    for g2 = 0:0.1:g1
        for b2=0:0.1:b1

            % calculate angle between two vectors
            P2 = [r2, g2, b2];
            a = abs(atan2(norm(cross(P1,P2)),dot(P1,P2)));
            
            % draw point if conditions are true
            if ((b1 - b2) < (g1 - g2)) && ((g1 - g2) <= (r1 - r2)) && (a < (pi/20)) 
                scatter3(r2,g2,b2,5,'g');
                hold on;
            end
            
        end
    end
end

如何应用这些条件并在 3D 空间中填充所有可能值的区域P2

标签: matlabplot3dscatter-plot

解决方案


您正在通过单独调用来绘制每个点scatter3。相反,您应该首先执行计算并找到点,然后一次将它们全部绘制出来:

r1 = 100; g1 = 102; b1 = 103;
P1 = [r1, g1, b1];
step = .5;
r = 0:step:r1;
g = 0:step:g1;
b = 0:step:b1;
[R, G, B] = meshgrid(r, g, b);
n = numel(R);
inside = false(size(R));
for ii= 1:n
    r2 = R(ii);
    g2 = G(ii);
    b2 = B(ii);
    
    % calculate angle between two vectors
    P2 = [r2, g2, b2];
    a = abs(atan2(norm(cross(P1,P2)),dot(P1,P2)));
    
    % draw point if conditions are true
    if ((b1 - b2) < (g1 - g2)) && ((g1 - g2) <= (r1 - r2)) && (a < (pi/20))
        inside(ii) = true;
    end
end
scatter3(R(inside), G(inside), B(inside), 5, 'g');

另外,如果您有兴趣说明体积,您可以调用convhull查找找到点的凸厅:

k = convhull(R(inside), G(inside), B(inside));
trisurf(k,R(inside), G(inside), B(inside), 'facecolor', 'g', 'edgealpha', .1)

您甚至可以简化凸包:

k = convhull(R(inside), G(inside), B(inside),'Simplify',true);

在此处输入图像描述

编辑:添加透明度

'MarkerEdgeAlpha'您可以通过设置其属性使散点图透明。但是,它可能不会对结果有太大的改变,除了体积的边缘。那是因为有太多的标记相互覆盖:

subplot 131
scatter3(R(inside), G(inside), B(inside), 5, 'r');
axis equal, title('solid')

subplot 132
scatter3(R(inside), G(inside), B(inside), 5, 'r', ...
    'markeredgealpha', 0.1);
axis equal, title('transparent')

subplot 133
scatter3(R(inside), G(inside), B(inside), 5, 'r', ...
    'markeredgealpha', 0.1);
axis equal, title('zoomed'), zoom(4)

在此处输入图像描述

您还可以使 surf 对象透明:

subplot 121
trisurf(k,R(inside), G(inside), B(inside), 'facecolor', 'g', ...
    'edgealpha', 0.1)
axis equal, title('solid')

subplot 122
trisurf(k,R(inside), G(inside), B(inside), 'facecolor', 'g', ...
    'facealpha', 0.3, 'edgealpha', .1)
axis equal, title('transparent')

在此处输入图像描述


推荐阅读