【问题标题】:Matlab - How to to fill an area in 3D space?Matlab - 如何填充 3D 空间中的区域?
【发布时间】:2020-12-29 21:20:53
【问题描述】:

我想使用一些条件填充 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 值填充该区域?

【问题讨论】:

    标签: matlab plot 3d scatter-plot


    【解决方案1】:

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

    【讨论】:

    • 谢谢。完美解决方案
    • 有没有办法增加表面的透明度?我尝试使用set(h, 'MarkerEdgeAlpha', alpha, 'MarkerFaceAlpha', alpha);,其中h 是散点图,但没有任何区别。
    • 我很高兴它帮助了@hadi jan。我编辑了可能会发布以添加透明度。
    • 感谢您的帮助。 facealpha 选项效果更好。
    猜你喜欢
    • 2017-08-30
    • 2013-11-23
    • 1970-01-01
    • 1970-01-01
    • 2017-11-09
    • 1970-01-01
    • 2013-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多