ARAP
来源:互联网 发布:telnet测试 lp 端口号 编辑:程序博客网 时间:2024/05/17 23:38
gptoolbox\mesh\arap.m
先以一个三角形为例
“arap.m”
Covariance Matrix
data.CSM = covariance_scatter_matrix(ref_V,ref_F,’Energy’,energy);
In function covariance_scatter_matrix, it constructed a covarience scatter matrix :
For internal two dimension, the column dimension is related to the each vertex in the mesh while the row dimension is about the neighbors of each vertex. Then the covarience scatter matrix is constructed by
Therefore, the first dimension of
% compute covariance matrix elements S = zeros(size(data.CSM,1),dim); S(:,1:dim) = data.CSM*repmat(U,dim,1); % dim by dim by n list of covariance matrices SS = permute(reshape(S,[size(data.CSM,1)/dim dim dim]),[2 3 1]);
Hence, using permute function , we change the dimension going through the vertex to the last so that covariance matrix are obtained for each vertex.
Right Hand Side
Then let us look at the right hand side of formula (8)
% precompute rhs premultiplier if ~isfield(data,'K') || isempty(data.K) [~,data.K] = arap_rhs(ref_V,ref_F,[],'Energy',energy); %if flat %data.K = repdiag(ref_map,dim) * data.K; %end end
%B = arap_rhs(V,F,R); Rcol = reshape(permute(R,[3 1 2]),size(data.K,2),1); Bcol = data.K * Rcol; B = reshape(Bcol,[size(Bcol,1)/dim dim]);
In function arap_rhs, it constructs a matrix K,
% K #V*dim by #(F|V)*dim*dim matrix such that:
% b = K * reshape(permute(R,[3 1 2]),size(V,1)*size(V,2)*size(V,2),1);
At first, matrix
For better explaining, we introduce an equation:
Looking at the left hand side and substituting
consequently, the result is a column vector, the first dimension goes though vertices(组内), the second dimension goes through
B = reshape(Bcol,[size(Bcol,1)/dim dim]);
This line enable the first dimension to go through vertices and the second dimension to go through
Minimization process
[U,data.preF] = min_quad_with_fixed( ... -0.5*data.L+DQ+alpha_tik*speye(size(data.L)), ... -B+Dl,b,bc,Aeq,Beq,data.preF);
searching upwards, we find
data.L = cotmatrix(V,F);
The details of cotmatrix can be found at http://blog.csdn.net/seamanj/article/details/53774501
DQ = sparse(size(V,1),size(V,1)); Dl = sparse(size(V,1),dim); % Tikhonov regularization alpha alpha_tik = 0;
Next, we solve the formula (9)
In code it uses minimizing quadratic energy method to solve the equation. Integrating both sides with respect to unknown
Note that there is a minus symbol before 0.5, that’s because the cotmatrix has negative enties on diagonal elements, which is the negative of laplacian matrix.
最后看下这个函数 arap_linear_block
这个函数充当两个角色
即可以算CSM 也可以算K,K用于线性化R, 而CSM是用来算covariance scatter matrix
K中block的转置就是CSM中的block, 为了满足CSM, 矩阵按行相加应该得到一个0行向量, 而要满足K只需要列中对应的部分相同, 则就可以让R相加
主要讲下spokes 和 spokes-and-rims 两种方法的区别
为了让block即满足CSM又要满足K, 我们将每个三角形的权值拆开, 每条边正反各迭代一次
算右边:
spokes中每条边只受两个旋转矩阵的影响, 即两个端点处旋转的影响
而spokes-and-rims 每 条边受以三个旋转矩阵的影响 .
算R:
spokes中算
而spokes-and-rims中算
function K = spokes_linear_block(V,F,d)% % Computes a matrix K such that K * R computes % % 鈭?wij * 0.5 * (V(i,d)-V(j,d)) * (Ri + Rj)% % j鈭圢(i)% % % % Inputs:% % V #V by dim list of coordinates% % F #F by 3 list of triangle indices into V% % d index into columns of V% % Output:% % K #V by #V matrix% %% E = edges(F); % % Build upper part of adjacency matrix where instead of a 1 for edge from i% % to j we have the difference of position in dimension d% A = sparse(E(:,1),E(:,2),V(E(:,1),d)-V(E(:,2),d),size(V,1),size(V,1));% % anti-symmetric, or considers direction of edges% A = A-A';% % Multiply with cotangent weights (don't worry about diagonal begin wrong% % since in A 0it's all zeros% L = cotmatrix(V,F);% K = L.*A;% % correct the diagonal (notice that the sign is positive% K = K + diag(sum(K,2));% K = 0.5*K;%权值在cotmatrix.m已除2,这里除2是匹配8式的0.5 % triangles C = cotangent(V,F); i1 = F(:,1); i2 = F(:,2); i3 = F(:,3); I = [i1;i2;i2;i3;i3;i1;i1;i2;i3]; J = [i2;i1;i3;i2;i1;i3;i1;i2;i3]; v = [ ... C(:,3).*(V(i1,d)-V(i2,d)) ; ... C(:,3).*(V(i2,d)-V(i1,d)); ... C(:,1).*(V(i2,d)-V(i3,d)); ... C(:,1).*(V(i3,d)-V(i2,d)); ... C(:,2).*(V(i3,d)-V(i1,d)) ; ... C(:,2).*(V(i1,d)-V(i3,d)); ... ... % diagonal C(:,3).*(V(i1,d)-V(i2,d)) + C(:,2).*(V(i1,d)-V(i3,d)); ... C(:,1).*(V(i2,d)-V(i3,d)) + C(:,3).*(V(i2,d)-V(i1,d)); ... C(:,2).*(V(i3,d)-V(i1,d)) + C(:,1).*(V(i3,d)-V(i2,d)); ... ]; % construct and divide by 3 so laplacian can be used as is K = sparse(I,J,v,n,n)/2; end function K = spokes_and_rims_linear_block(V,F,d) % Computes a matrix K such that K * R computes % 鈭? -2*(cot(aij) + cot(bij) * (V(i,d)-V(j,d)) * (Ri + Rj) + % -2*cot(aij) * (V(i,d)-V(j,d)) * Raij + % -2*cot(bij) * (V(i,d)-V(j,d)) * Rbij % j鈭圢(i) % % where: vj % / | \ % / | \ % / | \ % / | \ % aij | bij % \ | / % \ | / % \fij|gij/ % \ | / % vi % % Inputs: % V #V by dim list of coordinates % F #F by 3 list of triangle indices into V % d index into columns of V % Output: % K #V by #F matrix % if simplex_size == 3 % triangles C = cotangent(V,F); i1 = F(:,1); i2 = F(:,2); i3 = F(:,3); I = [i1;i2;i2;i3;i3;i1;i1;i2;i3]; J = [i2;i1;i3;i2;i1;i3;i1;i2;i3]; v = [ ... C(:,3).*(V(i1,d)-V(i2,d)) + C(:,2).*(V(i1,d)-V(i3,d)); ... -C(:,3).*(V(i1,d)-V(i2,d)) + C(:,1).*(V(i2,d)-V(i3,d)); ... C(:,1).*(V(i2,d)-V(i3,d)) + C(:,3).*(V(i2,d)-V(i1,d)); ... -C(:,1).*(V(i2,d)-V(i3,d)) + C(:,2).*(V(i3,d)-V(i1,d)); ... C(:,2).*(V(i3,d)-V(i1,d)) + C(:,1).*(V(i3,d)-V(i2,d)); ... -C(:,2).*(V(i3,d)-V(i1,d)) + C(:,3).*(V(i1,d)-V(i2,d)); ... ... % diagonal C(:,3).*(V(i1,d)-V(i2,d)) - C(:,2).*(V(i3,d)-V(i1,d)); ... C(:,1).*(V(i2,d)-V(i3,d)) - C(:,3).*(V(i1,d)-V(i2,d)); ... C(:,2).*(V(i3,d)-V(i1,d)) - C(:,1).*(V(i2,d)-V(i3,d)); ... ]; % construct and divide by 3 so laplacian can be used as is K = sparse(I,J,v,n,n)/3; elseif simplex_size == 4 % tetrahedra assert(false) end end
- ARAP
- xcodebuild' requires Xcode, but active developer directory '/Library/Developer/CommandLineTools' is
- enote笔记法使用范例(1)——自己总结的一些编写代码的常识 (a)
- 使用LinkedList存储一副扑克牌,然后进行洗牌
- linux 安装git
- String to Integer (atoi)
- ARAP
- 了解C语言
- 声明
- [代码笔记] python的函数定义之各种参数(必须,关键字,默认值,不定长)
- Java I/O(一)字节流与字符流
- bzoj2588 count on a tree 主席树
- Caffe 实例测试一: MNIST
- [代码笔记] python之 玩玩 while 我的九九归一
- LeetCode #216 - Combination Sum III - Medium