📄 compute_geodesic_mesh.m.svn-base
字号:
function [path,vlist,plist] = compute_geodesic_mesh(D, vertex, face, x, options)% compute_geodesic_mesh - extract a discrete geodesic on a mesh%% [path,vlist,plist] = compute_geodesic_mesh(D, vertex, face, x, options);%% D is the set of geodesic distances.%% path is a 3D curve that is the shortest path starting at x.% You can force to use a fully discrete descent using% options.method='discrete'.%% Copyright (c) 2007 Gabriel Peyreoptions.null = 0;verb = getoptions(options, 'verb', 1);if length(x)>1 path = {}; vlist = {}; plist = {}; for i=1:length(x) if length(x)>5 if verb progressbar(i,length(x)); end end [path{i},vlist{i},plist{i}] = compute_geodesic_mesh(D, vertex, face, x(i), options); end return;endmethod = getoptions(options, 'method', 'continuous');[vertex,face] = check_face_vertex(vertex,face);if strcmp(method, 'discrete') if isfield(options, 'v2v') vring = options.v2v; else vring = compute_vertex_ring(face); end % path purely on edges vlist = x; vprev = D(x); while true x0 = vlist(end); r = vring{x0}; [v,J] = min(D(r)); x = r(J); if v>=vprev || v==0 break; end vprev = v; vlist(end+1) = x; end path = vertex(:,vlist); plist = vlist*0+1; return;end%%% gradient descent on edges% retrieve adjacency listsm = size(face,2); n = size(vertex,2);% precompute the adjacency datasetsif isfield(options, 'e2f') e2f = options.e2f;else e2f = compute_edge_face_ring(face);endif isfield(options, 'v2v') v2v = options.v2v;else v2v = compute_vertex_ring(face);end% initialize the paths[w,f] = vertex_stepping(face, x, e2f, v2v, D);vlist = [x;w]; plist = [1];Dprev = D(x);while true; % current triangle i = vlist(1,end); j = vlist(2,end); k = get_vertex_face(face(:,f),i,j); a = D(i); b = D(j); c = D(k); % adjacent faces f1 = get_face_face(e2f, f, i,k); f2 = get_face_face(e2f, f, j,k); % compute gradient in local coordinates x = plist(end); y = 1-x; gr = [a-c;b-c]; % twist the gradient u = vertex(:,i) - vertex(:,k); v = vertex(:,j) - vertex(:,k); A = [u v]; A = (A'*A)^(-1); gr = A*gr; nx = gr(1); ny = gr(2); % compute intersection point etas = -y/ny; etat = -x/nx; s = x + etas*nx; t = y + etat*ny; if etas<0 && s>=0 && s<=1 && f1>0 %%% CASE 1 %%% plist(end+1) = s; vlist(:,end+1) = [i k]; % next face f = f1; elseif etat<0 && t>=0 && t<=1 && f2>0 %%% CASE 2 %%% plist(end+1) = t; vlist(:,end+1) = [j k]; % next face f = f2; else %%% CASE 3 %%% if a<=b z = i; else z = j; end [w,f] = vertex_stepping( face, z, e2f, v2v, D); vlist(:,end+1) = [z w]; plist(end+1) = 1; end Dnew = D(vlist(1,end))*plist(end) + D(vlist(2,end))*(1-plist(end)); if Dnew==0 || (Dprev==Dnew && length(plist)>1) break; end Dprev=Dnew;endv1 = vertex(:,vlist(1,:));v2 = vertex(:,vlist(2,:));path = v1.*repmat(plist, [3 1]) + v2.*repmat(1-plist, [3 1]);%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function [w,f] = vertex_stepping(face, v, e2f, v2v, D)% adjacent vertex with minimum distance[tmp,I] = min( D(v2v{v}) ); w = v2v{v}(I);f1 = e2f(v,w);f2 = e2f(w,v);if f1<0 f = f2; return;endif f2<0 f = f1; return;endz1 = get_vertex_face(face(:,f1),v,w);z2 = get_vertex_face(face(:,f2),v,w);if D(z1)<D(z2); f = f1; else f = f2;end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function k = get_vertex_face(f,v1,v2)if nargin==2 v2 = v1(2); v1 = v1(1);endk = setdiff(f, [v1 v2]);if length(k)~=1 error('Error in get_vertex_face');end%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%function f = get_face_face(e2f, f, i,j)f1 = e2f(i,j); f2 = e2f(j,i);if f==f1 f = f2;else f = f1;end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -