我有一个名为model_vertex的矩阵3x120000。它是来自stl文件的点云。 3个点指定三角形的顶点。所有3点它开始一个新的三角形。 我想找到具有相同三角形边的三角形。 这意味着三角形应该有2个相同的点。
我希望你能帮助我。我可以通过4个for循环来解决这个问题...但计算时间难以置信。
for i=1:length((model_vertex(1,:))/3)%every triangle in model_vertex
for n=i:length((model_vertex(1,:))/3)%every triangle besides i-triangle
match=0;
for j=1:3 %Search all vertex of triangle(i),
for k=1:3 %Search all vertex of triangle(n)
if model_vertex(1,(i-1)*3+j) == model_vertex(1,(n-1)*3+k) &&...
model_vertex(2,(i-1)*3+j) == model_vertex(2,(n-1)*3+k) &&...
model_vertex(3,(i-1)*3+j) == model_vertex(3,(n-1)*3+k)
match=match+1;
if match == 2
%triangle neighbour found
%save in an array
break
endif
endif
endfor
if match ==2
break
endif
endfor
endfor
endfor
答案 0 :(得分:2)
这是一种使用稀疏矩阵和矩阵乘法的方法。
s= sparse(reshape(repmat(1:40000,3,1),[],1),model_vertex(:),1);
out = s * s.';
[x y]=find(out);
或更多内存友好:
[x y v]=find(out);
idx = v == 2;
x2 = x(idx);
y2 = y(idx);
您可以创建[40000 40000]
[3 40000]
的{{1}}稀疏矩阵表示。然后进行矩阵乘法以计算相同点的数量。
答案 1 :(得分:0)
这是我的解决方案,利用许多内置函数来防止循环。一般想法:将每个三角形描述为一组三条线,然后搜索具有完全相同线条的其他三角形:
% generate dummy data
N = 40000;
model_vertex = randi(25,[3 3*N]);
% give vertices numbers, reduces the problem by a factor 3
[coord_label, ~, coord_id] = unique(model_vertex','rows');
triangle = reshape(coord_id,3,[]); % each column is a triangle, containing the triangle_coords id
triangle = sort(triangle); % this is important, otherwise A -> B vs B -> A is missed
% transform from coordinates to lines. A line is given by two vertices (so
% vertex1 to vertex2, vertex2 to vertex3 and 3 to 1)
[line_label, ~, line_id] = unique(reshape(triangle([1 2 2 3 1 3],:),2,[])','rows'); % a line is given by two vertices
% find matches. Speed up loop by sorting first
[s_line_id,b] = sort(line_id);
% data is sorted. Quick start search by only starting from element for
% which the next element is the same
sel = [s_line_id(1:end-1)==s_line_id(2:end); false];
% no pre-allocation, dont know how many items.
match = [];
for l = find(sel)'
triangle_id1 = ceil(b(l)/3);
for k=(l+1):(3*N)
if s_line_id(l)==s_line_id(k)
triangle_id2 = ceil(b(k)/3);
if triangle_id2~=triangle_id1 % check for fake triangle => has same line twice. Shoudld not occur in actual data
match = [match; [triangle_id1, triangle_id2]];
end
else
continue; % move on to next
end
end
end
% verify first solution
model_vertex_r = reshape(model_vertex,3,3,[]);
model_vertex_r(:,:,match(1,:))
我的笔记本电脑在1秒钟内运行。