フィルターのクリア

convert patch structure to graph() object?

18 ビュー (過去 30 日間)
Walter Roberson
Walter Roberson 2023 年 9 月 22 日
編集済み: 2024 年 3 月 7 日
Is there an easier / better way to convert a patch() faces / vertices structure to a graph object?
%Where S is a struct with faces and vertices
%such as returned by isosurface()
%patch() can deal directly with such struct
s = S.faces;
v = S.vertices;
t = circshift(S.faces, [0 -1]);
G = graph(s(:), t(:));
Although this code is not long, it took a bit of thinking about and experimenting to come up with; it feels to me as if there should be a better method.
Each row of the faces is a list of vertex numbers, with an implied return to the first vertex. This code constructs source and target lists by taking all adjacent pairs from the rows, including wrapping back from first to last.

回答 (3 件)

J. Alex Lee
J. Alex Lee 2023 年 9 月 22 日
編集済み: J. Alex Lee 2023 年 9 月 22 日
Are you sure your method is giving you the graph you want? It looks like it counts edges twice, but not exactly.
So my question is: there must be a better way to construct the self-adjacency matrix other than this brute force?
% create structure by isosurface
[x,y,z] = meshgrid([-3:1:3]);
V = x.*exp(-x.^2 -y.^2 -z.^2);
S = isosurface(x,y,z,V,1e-4);
% shortcut for connectivity matrix
c = S.faces;
%% Walter's graph
%Where S is a struct with faces and vertices
%such as returned by isosurface()
%patch() can deal directly with such struct
s = S.faces;
v = S.vertices;
t = circshift(S.faces, [0 -1]);
G = graph(s(:), t(:));
figure(1);
plot(G)
%% alternate graph
% number of nodes
n = height(S.vertices);
% construct self-adjacency matrix
A = spalloc(n,n,n*n);
for i = 1:n
[row,col] = find(S.faces==i);
v = unique(c(row,:));
A = A + sparse(i,v,1,n,n);
end
% have to remove the diagonals
A = A .* ~speye(n);
G_B = graph(A)
G_B =
graph with properties: Edges: [276×2 table] Nodes: [97×0 table]
figure(2);
plot(G_B)
  2 件のコメント
Walter Roberson
Walter Roberson 2023 年 9 月 22 日
編集済み: Walter Roberson 2023 年 9 月 22 日
Interesting point. Let's try
% create structure by isosurface
[x,y,z] = meshgrid([-3:1:3]);
V = x.*exp(-x.^2 -y.^2 -z.^2);
S = isosurface(x,y,z,V,1e-4);
% shortcut for connectivity matrix
c = S.faces;
%% Walter's graph
%Where S is a struct with faces and vertices
%such as returned by isosurface()
%patch() can deal directly with such struct
s = S.faces;
v = S.vertices;
t = circshift(S.faces, [0 -1]);
st = unique(sort([s(:), t(:)],2), 'rows');
G = graph(st(:,1), st(:,2))
G =
graph with properties: Edges: [276×1 table] Nodes: [97×0 table]
figure(1);
plot(G)
... all the more reason why it would be better to have a function to handle this.
J. Alex Lee
J. Alex Lee 2023 年 9 月 23 日
I now better understand how our methods are related: both concepts were discussed a while ago triangulation to adjacency.
I update my code for creating the adjacency matrix based on Akira's answer, using circshift for more generality - I guess the path through the sorted node pair list is more "direct" than this...but anyway for completeness.
c = S.faces;
t = circshift(c,[0 -1]);
A = sparse(c(:),t(:),1,n,n);
A = A | A.';

サインインしてコメントする。


J. Alex Lee
J. Alex Lee 2023 年 9 月 23 日
Found a more built-in way but you have to convert the structure to a triangulation
% create structure by isosurface
[x,y,z] = meshgrid([-3:1:3]);
V = x.*exp(-x.^2 -y.^2 -z.^2);
S = isosurface(x,y,z,V,1e-4);
TR = triangulation(S.faces,S.vertices);
st = edges(TR);
G = graph(st(:,1),st(:,2));
plot(G)

浩
2024 年 3 月 7 日
編集済み: 2024 年 3 月 7 日

カテゴリ

Help Center および File ExchangePolygons についてさらに検索

製品

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by