绘制图形-不同边缘的线型不同

时间:2019-05-20 09:43:07

标签: matlab

我有一个针对每个节点的(x, y, z)坐标所绘制的节点和边的图形。

我想用虚线表示“内部”边缘,而用直线表示“外部”边缘。

LineStyle可能会对我有所帮助,但我认为这会使我的所有边缘都变成虚线。我想指定哪些点是虚线的。

这是我用来绘制图形的代码:(G是图形)

plot(G, 'XData', A(1,:), 'YData', A(2,:), 'ZData', A(3,:))

非常感谢您的帮助!

我有一个创建图形的函数,它给出以下输出:

G =
graph with properties:
    Edges: [11×1 table]
    Nodes: [6×0 table] 

和类似的坐标系:

A =
     0     1     0    -1     0     0
     0     1     3     2     1     2
     1     1     1     1     1     1

使用上述绘图功能,将提供以下输出:

Output

1 个答案:

答案 0 :(得分:1)

好吧,您实际上并没有付出足够的努力来使每个人都容易回答您的问题,但是我对一种方法感到好奇,并且这种方法似乎可行,所以我还是将其发布。

在这些情况下,点/线子组与整个组的绘制方式不同的经典技巧是:

  1. 绘制整个组
  2. 在顶部用不同的线属性绘制子组

在您的情况下,这意味着您必须找到作为边界一部分的点和边。我将在下面说明一种方法。请注意,此方法仅适用于边界(请参见使用设置的区别,其中该方法不适用于concave vs. convex hull)。

首先我需要了解您的问题状态,所以让我们考虑:

%% Initial data
A =[ 0  1  0 -1  0  0
     0  1  3  2  1  2
     1  1  1  1  1  1 ];
G = graph ;
G = addedge(G,[1 1 1 1 1 2 2 2 3 4 4],[2 3 4 5 6 3 5 6 4 5 6]) ;
plot(G, 'XData', A(1,:), 'YData', A(2,:) , 'LineStyle','--')
grid on ; hold on
np = size(A,2) ;            % Number of points/nodes

这将产生与您完全一样的图形,只有一个linestyle,对于整个图形,该图形均设置为虚线。现在的工作是用实线绘制轮廓。

要找到轮廓(至少在像您这样的二维情况下),使用的方法是:

  1. 找到轮廓的一个点(初始点),即最低的x 可能。
  2. 计算单位向量ux=[1,0,0]与 所有其他向量(由初始点和所有其他 点矩阵)。
  3. 指定轮廓的下一个点(它是矢量具有的下一个点) 最小角度)。现在,您有一个当前向量vec(介于 点1和2),以及当前点pt2
  4. 计算vec与所有其他向量之间的夹角 根据当前点pt2和矩阵的所有其他点) 轮廓的下一个点是矢量具有 最小角度。
  5. 重复(3)和(4),直到轮廓的下一个点是 起点。

翻译成代码:

%% find a point on the edge
% (I chose to start with the lowest point on Y axis)
[~,idxNext] = min(A(2,:)) ;

%% initialise counters
isOnEdge = false(np,1) ;    % this will hold a logical register of contour points
idxEdge = idxNext ;         % this will hold the points of the contour, in order

%% setup start conditions
isOnEdge(idxNext) = true ;  % initial point
p = A(:,idxNext) ;          % initial point
v = [1;0;0] ;               % initial vector (start with unit vector oriented Ox)

%% search for contour
isRunning = true ;
iter = 0 ;
while isRunning
    iter = iter + 1 ;               % make sure we're not stuck in infinite loop
    angs = find_angles(v,p,A) ;     % find angles between initial vector and all other points
    angs(idxNext) = Inf ;           % Exclude current point
    if numel(idxEdge) > 1           % Exclude last point (if not at first iteration)
        angs(idxEdge(end-1)) = Inf ;      
    end
    [~,idxNext] = min(angs) ;       % find the index of the minimum angle 

    if isOnEdge(idxNext)
        % we've completed the close profile, bail out
        isRunning = false ;
    else
        % move on to next point/vector
        idxEdge = [idxEdge idxNext] ; %#ok<AGROW>
        isOnEdge(idxNext) = true ;
        p = A(:,idxNext) ;
        v = A(:,idxNext) - A(:,idxEdge(end-1)) ;
    end

    if iter > np
        break                       % make sure we're not stuck in infinite loop
    end
end

%% present results
if isRunning
    fprintf('Could''t find a closed profile\n')
else
    fprintf('Found points defining a closed profile:\n')
    disp(idxEdge)
end

%% Plot on top of graph
% create a matrix conataining only the contour points, close the contour by
% replicating the first point in last position
C = [A(:,idxEdge) , A(:,idxEdge(1))] ;
% plot
plot3( C(1,:) , C(2,:) , C(3,:) ,'b', 'LineWidth',2)
view(2)

哪个会产生:

enter image description here


在上面的脚本中,我正在使用功能find_angles.m。它的代码:

function angs = find_angles(Uin,p,M)
% find angle between Uin vector and the vectors formed between p and 
% all the points in M
np = size(M,2) ;
angs = zeros(np,1) ;
for iv=1:np
    vec = M(:,iv) - p ;
    c = cross(Uin,vec) ;
    d = dot(Uin,vec) ;
    angs(iv) = rad2deg( atan2( norm(c) , d ) ) * sign( c(3) ) ;

    % take care of an edge case
    if c(3)==0 && d==-1 ; angs(iv) = 180 ; end

    % give [0 360] degree results
    if angs(iv) < 0 ; angs(iv) = 180 + (180+angs(iv) ) ; end
end
相关问题