博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
cotangent matrix or laplacian mesh operator
阅读量:4040 次
发布时间:2019-05-24

本文共 4462 字,大约阅读时间需要 14 分钟。

Actually, stiffness matrix can be transformed to cotangent matrix. In regard to stiffness matrix please refer http://blog.csdn.net/seamanj/article/details/51359991

https://uk.mathworks.com/matlabcentral/fileexchange/49692-gptoolbox

C:\TestMatlab\alec_jacobson\alecjacobson-gptoolbox-9dc4ff4\mesh\cotmatrix.m

function L = cotmatrix(V,F)  % COTMATRIX computes cotangent matrix (laplacian mesh operator), (mass/area  % terms already cancelled out)  %  % L = cotmatrix(V,F)  % L = cotmatrix(V,T)  %  % For size(F,2)==4, This is distinctly NOT following definition that appears  % in the appendix of: ``Interactive Topology-aware Surface Reconstruction,''  % by Sharf, A. et al  % http://www.cs.bgu.ac.il/~asharf/Projects/InSuRe/Insure_siggraph_final.pdf  %  % Instead it is a purely geometric construction. Find more details in Section  % 1.1 of "Algorithms and Interfaces for Real-Time Deformation of 2D and 3D  % shapes" [Jacobson 2013]  %  % ND derivation given in "A MONOTONE FINITE ELEMENT SCHEME FOR  % CONVECTION-DIFFUSION EQUATIONS" [Xu & ZIKATANOV 1999]  %  % 3D derivation given in "Aspects of unstructured grids and finite-volume  % solvers for the Euler and Navier-Stokes equations" [Barth 1992]  %  %  % Inputs:  %   V  #V x dim matrix of vertex coordinates  %   F  #F x simplex-size matrix of indices of triangle or tetrahedron corners  % Outputs:  %   L  sparse #V x #V matrix of cot weights   %  % Copyright 2011, Alec Jacobson (jacobson@inf.ethz.ch), Denis Zorin  %  % See also: cotangent  %  ss = size(F,2);  switch ss  case 3    %% Could just replace everything with:    %C = cotangent(V,F);    %L = sparse(F(:,[2 3 1]), F(:,[3 1 2]), C,size(V,1),size(V,1));    %L = L+L';    %L = L-diag(sum(L,2));        % should change code below, so we don't need this transpose    if(size(F,1) == 3)      warning('F seems to be 3 by #F, it should be #F by 3');    end    F = F';    % renaming indices of vertices of triangles for convenience    i1 = F(1,:); i2 = F(2,:); i3 = F(3,:);     % #F x 3 matrices of triangle edge vectors, named after opposite vertices    v1 = V(i3,:) - V(i2,:);  v2 = V(i1,:) - V(i3,:); v3 = V(i2,:) - V(i1,:);    % computing *unsigned* areas     if size(V,2) == 2        % 2d vertex data        dblA = abs(v1(:,1).*v2(:,2)-v1(:,2).*v2(:,1));    elseif size(V,2) == 3        %n  = cross(v1,v2,2);  dblA  = multinorm(n,2);        % area of parallelogram is twice area of triangle        % area of parallelogram is || v1 x v2 ||         n  = cross(v1,v2,2);         % THIS DOES MATRIX NORM!!! don't use it!!        % dblA  = norm(n,2);        % This does correct l2 norm of rows        dblA = (sqrt(sum((n').^2)))';    else         error('unsupported vertex dimension %d', size(V,2))    end    % cotangents and diagonal entries for element matrices    cot12 = -dot(v1,v2,2)./dblA/2; cot23 = -dot(v2,v3,2)./dblA/2; cot31 = -dot(v3,v1,2)./dblA/2;    % diag entries computed from the condition that rows of the matrix sum up to 1    % (follows from  the element matrix formula E_{ij} = (v_i dot v_j)/4/A )    diag1 = -cot12-cot31; diag2 = -cot12-cot23; diag3 = -cot31-cot23;    % indices of nonzero elements in the matrix for sparse() constructor    i = [i1 i2 i2 i3 i3 i1  i1 i2 i3];    j = [i2 i1 i3 i2 i1 i3  i1 i2 i3];    % values corresponding to pairs form (i,j)    v = [cot12 cot12 cot23 cot23 cot31 cot31 diag1 diag2 diag3];    % for repeated indices (i,j) sparse automatically sums up elements, as we    % want    L = sparse(i,j,v,size(V,1),size(V,1));  case 4    if(size(F,1) == 4 && size(F,2) ~=4)      warning('F seems to be 4 by #F, it should be #F by 4');    end    % number of mesh vertices    n = size(V,1);    % cotangents of dihedral angles    C = cotangent(V,F);    %% TODO: fix cotangent to have better accuracy so this isn't necessary    %% Zero-out almost zeros to help sparsity    %C(abs(C)<10*eps) = 0;    % add to entries    L = sparse(F(:,[2 3 1 4 4 4]),F(:,[3 1 2 1 2 3]),C,n,n);    % add in other direction    L = L + L';    % diagonal is minus sum of offdiagonal entries    L = L - diag(sum(L,2));    %% divide by factor so that regular grid laplacian matches finite-difference    %% laplacian in interior    %L = L./(4+2/3*sqrt(3));    %% multiply by factor so that matches legacy laplacian in sign and    %% "off-by-factor-of-two-ness"    %L = L*0.5;    % flip sign to match cotmatix.m    if(all(diag(L)>0))      warning('Flipping sign of cotmatrix3, so that diag is negative');      L = -L;    end  endend

你可能感兴趣的文章
解析zookeeper的工作流程
查看>>
搞定Java面试中的数据结构问题
查看>>
慢慢欣赏linux make uImage流程
查看>>
linux内核学习(7)脱胎换骨解压缩的内核
查看>>
以太网基础知识
查看>>
慢慢欣赏linux 内核模块引用
查看>>
kprobe学习
查看>>
慢慢欣赏linux phy驱动初始化2
查看>>
慢慢欣赏linux CPU占用率学习
查看>>
2020年终总结
查看>>
Homebrew指令集
查看>>
React Native(一):搭建开发环境、出Hello World
查看>>
React Native(二):属性、状态
查看>>
JSX使用总结
查看>>
React Native(四):布局(使用Flexbox)
查看>>
React Native(七):Android双击Back键退出应用
查看>>
Android自定义apk名称、版本号自增
查看>>
adb command not found
查看>>
Xcode 启动页面禁用和显示
查看>>
【剑指offer】q50:树中结点的最近祖先
查看>>