Matlab - 如何填充 3D 区域 space?

Matlab - How to to fill an area in 3D space?

我想使用一些条件 space 填充 3D 区域。

假设有这样一个向量:

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

现在我想为 P2 = [x2, y2, z2]; 的所有可能值指明 space,例如:

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

我如何应用这些条件并为 P2 的所有可能值填充 3D space 区域?

您通过单独调用 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)

您还可以将冲浪对象设为透明:

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')