├── .gitignore ├── .gitmodules ├── LICENSE ├── README.md ├── examples ├── amoeba │ ├── amoeba.m │ └── amoeba_data │ │ ├── amoeba.json │ │ └── amoeba.png ├── bird │ ├── bird.m │ └── bird_mouth_data │ │ ├── bird_mouth.dmat │ │ ├── bird_mouth.json │ │ ├── bird_mouth.obj │ │ ├── bird_mouth.png │ │ ├── bird_mouth.tgf │ │ ├── bird_mouth_anim.txt │ │ └── bird_mouth_fixed_region.dmat ├── daisy │ ├── daisy.m │ └── daisy_data │ │ ├── daisy.dmat │ │ ├── daisy.json │ │ ├── daisy.obj │ │ ├── daisy.png │ │ ├── daisy.tgf │ │ └── daisy_anim.txt ├── hedgehog │ ├── hedgehog.m │ └── hedgehog_data │ │ ├── hedgehog.json │ │ ├── hedgehog.obj │ │ ├── hedgehog.png │ │ ├── hedgehog_C_idx.dmat │ │ └── hedgehog_T.dmat └── walrus │ ├── walrus.m │ └── walrus_data │ ├── walrus.json │ ├── walrus.obj │ ├── walrus.png │ ├── walrus_cage.tgf │ └── walrus_user_C.dmat ├── matlab-include ├── mex │ ├── compileAllMex.m │ ├── energy_hessian_mex.cpp │ ├── energy_hessian_mex.mexmaci64 │ ├── energy_value_mex.cpp │ ├── energy_value_mex.mexmaci64 │ ├── precompute_mex.cpp │ ├── precompute_mex.mexmaci64 │ ├── read_3d_bone_anim.cpp │ ├── read_3d_bone_anim.mexmaci64 │ ├── read_3d_pnt_anim.cpp │ ├── read_3d_pnt_anim.mexmaci64 │ ├── read_blendshape_anim.cpp │ └── read_blendshape_anim.mexmaci64 └── utils │ ├── build_selection_matrix.m │ ├── catmull_rom_handle.m │ ├── cluster_pnts_to_closest.m │ ├── default_D_matrix.m │ ├── edge_selection_matrix.m │ ├── lbs_matrix_xyz.m │ ├── mass_spring.m │ ├── massmatrix_xyz.m │ ├── newton_line_search.m │ ├── read_2d_bone_anim.m │ ├── read_2d_pnt_anim.m │ ├── save_bbw_bone.m │ ├── save_bbw_pnt.m │ ├── set_project_path.m │ ├── transform2d.m │ └── wire_deform.m └── showcases └── bird_out.gif /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | */.DS_Store -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "gptoolbox"] 2 | path = gptoolbox 3 | url = https://github.com/alecjacobson/gptoolbox.git 4 | [submodule "Bartels"] 5 | path = Bartels 6 | url = https://github.com/dilevin/Bartels.git 7 | [submodule "libigl"] 8 | path = libigl 9 | url = https://github.com/libigl/libigl.git 10 | [submodule "triangle"] 11 | path = triangle 12 | url = https://github.com/libigl/triangle.git 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Jiayi Eris Zhang, Seungbae Bang, David I.W. Levin, Alec Jacobson 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Complementary Dynamics 2 | 3 | Public Matlab code release for the SIGGRAPH Asia 2020 paper [Complementary Dynamics](https://www.dgp.toronto.edu/projects/complementary-dynamics/) by Jiayi Eris Zhang, Seungbae Bang, David I.W. Levin and Alec Jacobson. 4 | 5 | # Dependency 6 | 7 | [libigl](https://github.com/libigl)\ 8 | [gptoolbox](https://github.com/alecjacobson/gptoolbox)\ 9 | [Bartels](https://github.com/dilevin/Bartels)\ 10 | [triangle](https://github.com/libigl/triangle) 11 | 12 | # Setup 13 | 14 | Before running the code, you need to setup the following.\ 15 | Compile mex functions in Bartels: 16 | 17 | cd Bartles/matlab 18 | mkdir build 19 | cd build 20 | cmake .. 21 | make -j8 22 | 23 | Compile mex functions in gptoolbox: 24 | 25 | cd gptoolbox/mex 26 | mkdir build 27 | cd build 28 | cmake .. 29 | make -j8 30 | 31 | make sure `gptoolbox/wrappers/path_to_triangle.m` to indiciate your [tirangle](https://github.com/libigl/triangle) binary. 32 | 33 | Compile mex functions in `matlab-include/mex` by running `matlab-include/mex/compileAllMex.m` in Matlab. 34 | 35 | 36 | # Run 37 | 38 | This code runs in Matlab.\ 39 | Before running examples, make sure to `addpath` your root directory of this project.\ 40 | Then, try run examples scripts in `examples` in Matlab.\ 41 | For example, try run `examples\bird\bird.m` and you should be getting result like this: 42 | 43 | 44 | 45 | 46 | # Bibtex 47 | 48 | @article{Zhang:CompDynamics:2020, 49 | title = {Complementary Dynamics}, 50 | author = {Jiayi Eris Zhang and Seungbae Bang and David I.W. Levin and Alec Jacobson}, 51 | year = {2020}, 52 | journal = {ACM Transactions on Graphics}, 53 | } 54 | -------------------------------------------------------------------------------- /examples/amoeba/amoeba.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | warning('off','all'); 3 | addpath('../../matlab-include/utils'); 4 | set_project_path(); 5 | 6 | 7 | % read json 8 | json = jsondecode(fileread('./amoeba_data/amoeba.json')); 9 | cellfun(@(x,y) assignin('base',x,y),fieldnames(json),struct2cell(json)); 10 | 11 | 12 | [TT,~,TA] = imread(image_file); 13 | TT = im2double(TT); 14 | [V,F] = bwmesh(TA,'SmoothingIters',10,'Tol',1); 15 | UV = V; 16 | 17 | 18 | % rendering setup 19 | [~,b] = farthest_points(V,5); 20 | H = kharmonic(V,F,b,linspace(0,1,numel(b))'); 21 | if rendering 22 | % mode = 'view-in-figure-2'; 23 | % mode = 'gif'; 24 | mode = 'png-sequence'; 25 | switch mode 26 | case 'view-in-figure-2' 27 | close all; 28 | figure('WindowSTyle','docked'); 29 | figure('WindowSTyle','docked'); 30 | figure(1); 31 | end 32 | end 33 | 34 | % normalize the mesh 35 | V = V(:,1:2); 36 | V = V-(min(V)+max(V))*0.5; 37 | V = V/max(V(:)); 38 | 39 | % linear elasticity 40 | [~,~,data] = linear_elasticity(V,F,[],[],'Mu',mu,'Lambda',lambda); 41 | K = data.K; 42 | M = data.M; 43 | vec = @(X) X(:); 44 | g = 0*vec(repmat([0 -9.8],size(V,1),1)); % external force 45 | VH = [V ones(size(V,1),1)]; 46 | A = sparse(repdiag(VH,size(V,2))); % single handle 47 | 48 | 49 | % viewer 50 | clf; 51 | hold on; 52 | [X,Y] = meshgrid((min(V(:,1))-1):0.1:(max(V(:,1))+1),(min(V(:,2))-1):0.1:(max(V(:,2))+1)); 53 | [GF,GV] = surf2patch(X,Y,0*X); 54 | q = quiver(GV(:,1),GV(:,2),0*GV(:,1),0*GV(:,2),'linewidth',2,'color',[145, 224, 255]/255); 55 | t = tsurf(F,V,'EdgeColor','none'); 56 | hold off; 57 | axis equal; 58 | expand_axis(0.9); 59 | axis manual; 60 | drawnow; 61 | % Remove the axis and make the background color white 62 | set(gca,'Position',[0 0 1 1],'Visible','off'); 63 | set(gcf,'Color','w'); 64 | 65 | 66 | Z = zeros(size(A,2),1); 67 | U = vec(zeros(size(V))); 68 | Ud = vec(zeros(size(V))); 69 | Uc = vec(zeros(size(V))); 70 | T = [0 0]; 71 | 72 | 73 | for iter = 1:frame_num 74 | 75 | Z0 = Z; 76 | Ud0 = Ud; 77 | U0 = U; 78 | 79 | % script the input motion 80 | time = 0.025 * iter; 81 | T(end) = (sin(0.5*time))*0.6; 82 | th = sin(0.5*time)*0.05; 83 | Z = vec([[cos(th) sin(th);-sin(th) cos(th)] - eye(2,2);T]); 84 | gfun = @(V) [max(sin(-6*time+V(:,1)*5),0) zeros(size(V,1),1)]; 85 | g = vec(6e1*gfun(V)); 86 | 87 | mqwf = {}; 88 | mqwf.force_Aeq_li = true; 89 | [Uc,mqwf] = min_quad_with_fixed( ... 90 | 0.5*(K+M/(dt^2)), ... 91 | M*(A*(Z - Z0))/(dt^2)-M*(g+Uc/dt^2+Ud0/dt), ... 92 | [],[], ... 93 | A' * M,zeros(size(A,2),1), ... 94 | mqwf); 95 | 96 | U = A*Z + Uc; 97 | Ud = (U-U0)/dt; 98 | 99 | % visualization 100 | t.Vertices = [V+reshape(U,size(V)) H]; 101 | gGV = gfun(GV); 102 | set(q,'XData',GV(:,1),'YData',GV(:,2),'UData',gGV(:,1),'VData',gGV(:,2)); 103 | title(sprintf('%d',iter),'Fontsize',20); 104 | drawnow; 105 | 106 | if rendering 107 | [IO,AA] = apply_texture_map(t,UV,TT); 108 | % show image or write to file 109 | switch mode 110 | case 'view-in-figure-2' 111 | figure(2); 112 | imshow(IO); 113 | set(gca,'Position',[0 0 1 1]); 114 | drawnow; 115 | figure(1); 116 | case 'gif' 117 | filename = './output/amoeba.gif'; 118 | f = exist(filename,'file'); 119 | [SIf,cm] = rgb2ind(IO,256); 120 | if ~f 121 | imwrite(SIf,cm,filename,'Loop',Inf,'Delay',0); 122 | else 123 | imwrite(SIf,cm,filename,'WriteMode','append','Delay',0); 124 | end 125 | case 'png-sequence' 126 | imwrite(IO,sprintf('./output/amoeba%04d.png',iter),'Alpha',1*AA); 127 | end 128 | end 129 | end 130 | 131 | 132 | -------------------------------------------------------------------------------- /examples/amoeba/amoeba_data/amoeba.json: -------------------------------------------------------------------------------- 1 | { 2 | "image_file": "./amoeba_data/amoeba.png", 3 | "dt": 0.056, 4 | "mu": 5e1, 5 | "lambda": 1e-5, 6 | "frame_num": 500, 7 | "rendering": false 8 | } 9 | -------------------------------------------------------------------------------- /examples/amoeba/amoeba_data/amoeba.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/examples/amoeba/amoeba_data/amoeba.png -------------------------------------------------------------------------------- /examples/bird/bird.m: -------------------------------------------------------------------------------- 1 | clear; 2 | warning('off','all'); 3 | addpath('../../matlab-include/utils'); 4 | set_project_path(); 5 | 6 | % read json 7 | json = jsondecode(fileread('./bird_mouth_data/bird_mouth.json')); 8 | cellfun(@(x,y) assignin('base',x,y),fieldnames(json),struct2cell(json)); 9 | 10 | %[V,F] = load_mesh(mesh_file); 11 | [V,F,UV,TF] = readOBJ(mesh_file); 12 | [C,~,P,BE,CE,~] = readTGF(handle_file); 13 | V = V(:,1:2); 14 | C = C(:,1:2); 15 | [~,b] = farthest_points(V,5); 16 | H = kharmonic(V,F,b,linspace(0,1,numel(b))'); 17 | 18 | % import handle transformations 19 | T_list = read_2d_bone_anim(anim_file,C,BE); 20 | [W] = save_bbw_bone('./bird_mouth_data/bird_mouth.dmat',V,F,C,P,BE); 21 | VM = lbs_matrix(V,W); 22 | 23 | clf; 24 | hold on; 25 | t = tsurf(F,V,'FaceColor',blue,'FaceAlpha',0.8,'EdgeAlpha',0.8); 26 | hold off; 27 | axis equal; 28 | axis(5*[-0.5 2.3 -0.3 0.3]); 29 | axis manual; 30 | drawnow; 31 | 32 | % normalize the mesh 33 | mesh_center = (max(V)+min(V))/2; 34 | V = V - mesh_center; 35 | mesh_scale = max(V(:)); 36 | V = V/mesh_scale; 37 | C = C - mesh_center; 38 | C = C/mesh_scale; 39 | 40 | 41 | vec = @(X) reshape(X',size(X,1)*size(X,2),1); 42 | 43 | M = massmatrix_xyz(V,F); 44 | A = lbs_matrix_xyz(V,W); 45 | 46 | % no external force use the default D matrix 47 | [phi,Em] = default_D_matrix(V,F); 48 | 49 | g = 0*vec(repmat([0 -9.8],size(V,1),1)); % didn't add any external gravity in this example 50 | mask = M * phi; 51 | Aeq = A'*mask; 52 | Beq = zeros(size(A', 1),1); 53 | 54 | % Bartels 55 | [lambda, mu] = emu_to_lame(YM*ones(size(F,1),1), pr*ones(size(F,1),1)); 56 | dX = linear_tri2dmesh_dphi_dX(V,F); 57 | areas = triangle_area(V,F); 58 | 59 | % arap 60 | energy_func = @(a,b,c,d,e) linear_tri2dmesh_arap_q(a,b,c,d,e,[0.5*lambda,mu]); 61 | gradient_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq(a,b,c,d,e,[0.5*lambda,mu]); 62 | hessian_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq2(a,b,c,d,e,[0.5*lambda,mu],'fixed'); 63 | 64 | 65 | % Don't move 66 | U = vec(zeros(size(V))); 67 | Ud = vec(zeros(size(V))); 68 | Uc = vec(zeros(size(V))); 69 | 70 | T = zeros(1,size(T_list,1)); 71 | 72 | for ai=1:size(T_list,1) 73 | 74 | tic; 75 | 76 | % read a new frame 77 | TCol = T_list{ai,1}; 78 | UCol = VM*TCol; 79 | Ur = reshape(UCol, size(V)); 80 | % normalize the mesh [0 1 0 1]: units are meters 81 | Ur = Ur-mesh_center; 82 | Ur = Ur/mesh_scale; 83 | 84 | Ur = vec(Ur-V); 85 | 86 | 87 | Ud0 = Ud; 88 | U0 = U; 89 | 90 | 91 | if with_dynamics 92 | 93 | 94 | % instead of one direct solve: do newton here 95 | max_iter = 20; 96 | % Uc = vec(zeros(size(V))); % initial guess for Uc 97 | for i = 1 : max_iter 98 | alpha = 1; 99 | p = 0.5; 100 | c = 1e-8; 101 | 102 | % total energy = gravitational potential energy + kinetic energy + 103 | % elastic potential energy 104 | G = gradient_func(V,F,vec(V)+Ur+Uc,dX,areas); 105 | K = hessian_func(V,F,vec(V)+Ur+Uc,dX,areas); 106 | 107 | f = @(Ur,Uc) -(M*g)'*(vec(V)+Ur+Uc) + 0.5*(Ur+Uc-U0-dt*Ud0)'*M/(dt*dt)*(Ur+Uc-U0-dt*Ud0) + ... 108 | energy_func(V,F,vec(V)+Ur+Uc,dX,areas); 109 | 110 | tmp_H = M/(dt^2) + K; 111 | tmp_g = M/(dt^2) * (Ur+Uc) - M*(g+U0/dt^2+Ud0/dt) + G; 112 | 113 | % solve for the update 114 | tmp_H = 0.5 * (tmp_H + tmp_H'); 115 | dUc = speye(size(tmp_H,1),size(tmp_H,1)+size(Aeq,1)) * ([tmp_H Aeq';Aeq sparse(size(Aeq,1),size(Aeq,1))] \ [-tmp_g;Beq]); 116 | 117 | % check for newton convergence criterian 118 | if tmp_g'*dUc > -1e-6 119 | break; 120 | end 121 | 122 | % backtracking line search 123 | alpha = newton_line_search(f,tmp_g,dUc,Ur,Uc); 124 | Uc = Uc + alpha * dUc; 125 | end 126 | end 127 | 128 | U = Ur + Uc; 129 | Ud = (U-U0)/dt; 130 | 131 | t.Vertices = V+reshape(U,size(V,2),size(V,1))'; 132 | title(sprintf('%d',ai),'Fontsize',20); 133 | drawnow; 134 | end 135 | 136 | -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth.dmat: -------------------------------------------------------------------------------- 1 | 3 639 2 | 4.849902540505643e-13 3 | 5.448097088212201e-13 4 | 5.415227862224883e-13 5 | 5.092112343219725e-13 6 | 2.079649823586182e-13 7 | 2.181351502302986e-23 8 | 1.81037283406871e-14 9 | 9.56783788446641e-14 10 | 1.104350627179617e-13 11 | 1.113726553889613e-13 12 | 1.031998320001838e-13 13 | 4.71153438982918e-14 14 | 0.000132106163342884 15 | 0.002010164833855904 16 | 0.004458941962285035 17 | 0.0211571439058631 18 | 0.07450731990312211 19 | 0.1849288863682929 20 | 0.2026315781159773 21 | 0.2185519043117554 22 | 0.2346220156492972 23 | 0.2358229147871935 24 | 0.2601929669771487 25 | 0.3553170443271446 26 | 0.4980113651495889 27 | 0.5247370548198322 28 | 0.5412390608894747 29 | 0.5497051896226054 30 | 0.5514225892196644 31 | 0.5554930752883436 32 | 0.5555783483461449 33 | 0.5565698176173464 34 | 0.5690793357460963 35 | 0.5916259564228337 36 | 0.593069074000911 37 | 0.5949599648215281 38 | 0.5956095566158487 39 | 0.5956146747938859 40 | 0.5955775593346166 41 | 0.5968131077127217 42 | 0.6097627879721124 43 | 0.6098259030401819 44 | 0.6098448491021428 45 | 0.6100864810778709 46 | 0.6101068743329608 47 | 0.6091863764920845 48 | 0.6355186227566583 49 | 0.7509142793476136 50 | 0.8360386629551518 51 | 0.9425725065521677 52 | 0.9734121802231556 53 | 0.9912997203436907 54 | 0.999922483953231 55 | 0.9999999999991844 56 | 0.9999999999990786 57 | 0.9999999999990803 58 | 0.9999999999990927 59 | 0.9999999999984905 60 | 0.9999999999983603 61 | 0.9999999999979202 62 | 0.9999999999979038 63 | 0.9999999999979051 64 | 0.999999999997938 65 | 0.9999999999982002 66 | 0.9999999999996434 67 | 0.9999999999998589 68 | 0.9999996283189665 69 | 0.9999905988976359 70 | 0.9830620604068696 71 | 0.8158378947935998 72 | 0.5688492929321706 73 | 0.1764584420658869 74 | 0.02650145676027805 75 | 1.31726063752623e-13 76 | 2.061690121499249e-13 77 | 2.042664891530943e-13 78 | 1.541037104113962e-13 79 | 1.497276060303774e-13 80 | 1.333496375483604e-13 81 | 1.042696030584515e-13 82 | 1.66055478490358e-13 83 | 1.650115099339808e-13 84 | 1.532491599483336e-13 85 | 9.940101486577326e-14 86 | 1.644227869802099e-13 87 | 2.544538919733524e-13 88 | 3.589874746204374e-13 89 | 3.733415683448402e-13 90 | 3.351785272745858e-13 91 | 4.081619021473443e-13 92 | 6.228617824043165e-13 93 | 8.140645412413753e-13 94 | 1.225180913796432e-12 95 | 1.366334472379599e-12 96 | 1.268050139975141e-12 97 | 1.092140838720033e-12 98 | 9.934071356857894e-13 99 | 7.509810318817281e-13 100 | 4.495621457370089e-13 101 | 4.84655676600674e-14 102 | 4.484054047976162e-14 103 | 2.398922841304076e-13 104 | 2.554975446215935e-13 105 | 2.552138348091523e-13 106 | 1.732743705035332e-13 107 | 1.967406627716382e-13 108 | 2.256219510576807e-13 109 | 2.468137766824057e-13 110 | 2.545749284465366e-13 111 | 2.547899703585581e-13 112 | 1.710920546379462e-13 113 | 1.391495391790698e-13 114 | 2.37249883537527e-13 115 | 3.519613780959941e-13 116 | 2.366094865470104e-13 117 | 2.776276329952348e-14 118 | 2.502859189219189e-13 119 | 2.518295664846927e-13 120 | 0.5954304613054708 121 | 2.531673103211897e-13 122 | 2.454454365680252e-13 123 | 0.1973976843830942 124 | 0.2417092275936933 125 | 0.5255181731625902 126 | 0.6097947720114988 127 | 0.001755760782222704 128 | 4.798145401646281e-14 129 | 2.825415056476921e-14 130 | 0.6076076952461581 131 | 0.6099333533125076 132 | 0.6091488715385185 133 | 0.6097644111381404 134 | 0.6095568486222829 135 | 0.6094786033811009 136 | 2.332763932630612e-13 137 | 1.346781871731237e-13 138 | 0.5955796186854866 139 | 2.379045336579472e-13 140 | 0.2277548880777845 141 | 1.513716183260679e-13 142 | 0.5944581191101245 143 | 2.271342444916707e-13 144 | 0.2358405134266186 145 | 0.5952006869222553 146 | 1.980507552155259e-13 147 | 0.2424931004613225 148 | 0.5954467947397374 149 | 0.5543864165274686 150 | 0.1194252574310461 151 | 2.41382558257112e-13 152 | 0.2298188731466498 153 | 0.2553380264545472 154 | 0.5952566324413253 155 | 0.5551901021723129 156 | 0.2186908627055628 157 | 0.5552944522876151 158 | 1.019826913856893e-13 159 | 0.5508137839477275 160 | 2.832039416836785e-13 161 | 0.9999999999979657 162 | 0.4963903685601934 163 | 0.000255940628680278 164 | 2.873243189458926e-24 165 | 0.003419368194526377 166 | 2.313038253312647e-13 167 | 0.6091977836913115 168 | 1.490770305396457e-13 169 | 0.2177001981576491 170 | 0.5360885564515298 171 | 0.5534448356025329 172 | 6.969417171802405e-23 173 | 1.235893272221419e-13 174 | 8.997048250239029e-14 175 | 0.5598086918176173 176 | 0.5534875513910008 177 | 0.5677712804120645 178 | 0.5582772687744073 179 | 5.340484061267843e-13 180 | 0.5948117626763362 181 | 5.586794824095718e-14 182 | 7.812551000528147e-14 183 | 0.1848126176011504 184 | 0.5561949632497326 185 | 2.146417078836612e-24 186 | 0.0002487379918228195 187 | 1.128737034567089e-13 188 | 0.2656984316102569 189 | 0.9999999999985414 190 | 9.222759487709517e-14 191 | 0.1551440312542421 192 | 0.3093321749210879 193 | 0.6095870766549941 194 | 3.552493596673104e-13 195 | 0.5855607264924668 196 | 0.5848254643583043 197 | 0.5933166360515588 198 | 5.888539806256569e-14 199 | 2.355986960983395e-23 200 | 6.276956609669303e-14 201 | 2.616562737973389e-14 202 | 1.117157349164473e-13 203 | 0.1231760965995981 204 | 4.944051949749712e-13 205 | 0.4077079934505309 206 | 0.7730025208436095 207 | 0.0002085138416689557 208 | 0.01334318766994544 209 | 0.5435384286012408 210 | 0.6078157126422475 211 | 9.683876548317269e-13 212 | 1.079144230901901e-23 213 | 2.064997325882462e-14 214 | 0.552772569968942 215 | 1.777098563419439e-05 216 | 1.600483717821659e-14 217 | 6.300646028970571e-24 218 | 3.257741808357512e-13 219 | 9.579823352239504e-14 220 | 0.9999999999980961 221 | 0.5870630622833075 222 | 0.1058594718134707 223 | 6.751655382002212e-13 224 | 2.542805710177066e-13 225 | 0.004357532096026359 226 | 0.04292384797797744 227 | 0.8308508403662413 228 | 3.067419840869906e-13 229 | 1.79945560858655e-13 230 | 0.5906179361230545 231 | 8.144412335558193e-13 232 | 0.007134423052745541 233 | 1.683185778301142e-14 234 | 0.06555511476253582 235 | 1.57092244096704e-13 236 | 1.122622167404456e-13 237 | 0.5938088479615755 238 | 1.049440966944915e-12 239 | 6.98197419519614e-13 240 | 0.0005446722336487864 241 | 0.02527017904133864 242 | 0.5926889950359088 243 | 4.404440497476827e-13 244 | 8.061261581365013e-25 245 | 3.797188485013242e-25 246 | 2.768774946011404e-13 247 | 1.984358297251094e-13 248 | 0.9684006218410123 249 | 0.5937231969606419 250 | 1.354481263332888e-13 251 | 3.21615175009402e-23 252 | 0.6044113896629134 253 | 9.962093491515298e-14 254 | 0 255 | 3.251462172706812e-14 256 | 1.10053896459836e-13 257 | 1.449142201865489e-13 258 | 1.677942269305744e-13 259 | 0.4373531557793895 260 | 8.769513938101316e-14 261 | 1.17993654981507e-13 262 | 1.600645828454876e-14 263 | 0.5941627471325931 264 | 1.098053409110707e-12 265 | 8.657578473383462e-13 266 | 0.01570866744507382 267 | 4.001176708730289e-13 268 | 4.561181027464178e-13 269 | 3.294691033353269e-13 270 | 0.9606277553166772 271 | 0.4389407154363698 272 | 0.3618170239013068 273 | 0.4942687035587339 274 | 0.5126617232344985 275 | 0.3561866714034246 276 | 0.6692152620315591 277 | 0.442745715382921 278 | 0.5757565337459236 279 | 0.3223492077942459 280 | 0.526736039629273 281 | 0.674415845958666 282 | 0.5689557582411388 283 | 0.4609990111814897 284 | 0.7250514615879377 285 | 0.3561343419735745 286 | 1.556953196987921e-13 287 | 2.63987048309898e-13 288 | 8.10279474206368e-14 289 | 1.055905414348251e-12 290 | 0.002449495922548079 291 | 1.918360055008736e-13 292 | 3.819453719013665e-13 293 | 3.560144154355502e-13 294 | 2.777105439769764e-13 295 | 0.9199355398400263 296 | 0.9885432190111829 297 | 0.1767401444215929 298 | 2.442385956485023e-14 299 | 1.79877400524569e-13 300 | 8.75575196407375e-25 301 | 1.165904409973195e-14 302 | 0.03327154814880202 303 | 1.107077111275332e-14 304 | 6.937477543286213e-14 305 | 3.142690403661608e-13 306 | 2.168123297451835e-13 307 | 7.511313632805712e-14 308 | 0.8614580394725267 309 | 0.9777615591127107 310 | 0.2528868566452264 311 | 0.2113554697506275 312 | 0.2200599171756557 313 | 1.100063843574641e-13 314 | 2.831386248925291e-13 315 | 3.569185317400026e-14 316 | 8.549331584922211e-14 317 | 1.135562735307693e-13 318 | 0.08940678367428799 319 | 0.03479972399231804 320 | 0.01664556157680281 321 | 4.850377625589826e-13 322 | 2.148127980567128e-13 323 | 2.607838012255759e-13 324 | 3.305647937348865e-13 325 | 0.2613189436009239 326 | 0.1828941145814372 327 | 0.1481877727636182 328 | 0.08977445751260119 329 | 4.518089799850617e-14 330 | 0.0001465245707245568 331 | 3.913375385318316e-14 332 | 3.664471352101546e-14 333 | 1.992518455376127e-13 334 | 2.508234363110198e-13 335 | 2.313691427174939e-13 336 | 6.379441453067813e-13 337 | 1.347187125821906e-13 338 | 4.380432275697686e-13 339 | 4.215305942132165e-13 340 | 3.146316995171816e-13 341 | 3.643320628391977e-13 342 | 5.565091631668699e-14 343 | 3.148020396001724e-13 344 | 2.522946853818808e-13 345 | 3.485407685358558e-13 346 | 5.33987573774209e-25 347 | 0.00265845627727118 348 | 4.637102233876334e-15 349 | 0 350 | 3.052236037798429e-13 351 | 6.51681221596132e-13 352 | 7.828286050481992e-13 353 | 4.5191800921917e-14 354 | 3.412704680382156e-14 355 | 5.653943155829797e-14 356 | 9.468524616238382e-15 357 | 0 358 | 2.10938206809658e-14 359 | 0 360 | 6.796079373638439e-14 361 | 8.396590180533157e-14 362 | 1.050150995710217e-13 363 | 4.83133419140155e-13 364 | 8.621203360250133e-13 365 | 7.610352867177671e-13 366 | 1.115948557174579e-12 367 | 7.73335388180784e-13 368 | 3.300422281601941e-25 369 | 0.0005034537570007187 370 | 8.790005180038941e-14 371 | 1.149879330671794e-13 372 | 4.712218503134967e-14 373 | 1.459382269864442e-13 374 | 1.351151152355464e-13 375 | 1.189472394250788e-13 376 | 9.997803437440866e-13 377 | 1.422717440868386e-14 378 | 1.145706714887883e-12 379 | 0.9999999999994544 380 | 0.9999999999988964 381 | 0.5945016970159199 382 | 0.5748066472523593 383 | 0.6191112610350724 384 | 7.602230614624994e-14 385 | 0.9999999999982405 386 | 0.9999999999990662 387 | 0.999999999998152 388 | 0.9999999999984797 389 | 0.999999999998112 390 | 0.9999999999990065 391 | 4.398600142838584e-13 392 | 0.04661312443216547 393 | 0.06524614256734378 394 | 0.3077231597515315 395 | 1.805309510961304e-13 396 | 0.6122909939058904 397 | 0.3243147257627164 398 | 0.718420123072687 399 | 0.7528105656415019 400 | 0.797030339440208 401 | 0.912415334216938 402 | 0.8511332504964909 403 | 0.8067550210324124 404 | 0.9865961765000081 405 | 0.7858797015940806 406 | 0.9278982452080103 407 | 0.6047351245326549 408 | 0.9168892065920038 409 | 0.9923493037675652 410 | 1 411 | 0.9546403278848217 412 | 0.9369575961513721 413 | 0.8972330705140895 414 | 0.9920283306051259 415 | 0.9429145426421257 416 | 0.9981774398329309 417 | 0.9776243782676347 418 | 1 419 | 0.9996808371677047 420 | 0.9493844733029512 421 | 0.9628334562801252 422 | 0.5299544865284503 423 | 0.9834116365999002 424 | 0.9989322098317427 425 | 0.9454383553091675 426 | 0.9069649727329752 427 | 0.9382256032666529 428 | 0.5259339067379415 429 | 0.7043308476144898 430 | 0.6629382725854596 431 | 0.5504613826762375 432 | 0.999999999999966 433 | 0.9774377517258074 434 | 0.9463166399445133 435 | 2.970903546610717e-27 436 | 0.7231681768280156 437 | 0.03768646110847199 438 | 1 439 | 0.9996165695470726 440 | 0.9954377350475186 441 | 0.08929331800689223 442 | 0.2103570349761582 443 | 0.9899185871041184 444 | 0.9999969458346788 445 | 0.9853092947389865 446 | 0.9940769784170174 447 | 0.9920539314213702 448 | 0.9993668456208774 449 | 0.9962723873594261 450 | 0.9980688914222794 451 | 0.9994577792371198 452 | 0.9999711635615349 453 | 0.9991399986344514 454 | 0.9999533163228465 455 | 0.9999999218365879 456 | 0.9981636296165928 457 | 0 458 | 0.004352444666447157 459 | 0.3117776546925488 460 | 0.9755697452174958 461 | 0.99999999999997 462 | 0.9999999999997837 463 | 0.9968186747844793 464 | 8.34337128277421e-28 465 | 0.1090280271143138 466 | 0.08613761978693613 467 | 0.9999980002351725 468 | 1 469 | 0.9999999251719792 470 | 0.9999999999999641 471 | 0.9999999999999759 472 | 0.9999999999997622 473 | 0.9999999999999928 474 | 0.9999999999999238 475 | 0.9910485170496717 476 | 0.2072599957093275 477 | 0.02220996895541269 478 | 5.078076994729808e-14 479 | 1.584915989107872e-14 480 | 1.968707648645272e-13 481 | 4.908032584510573e-14 482 | 0.01334669007122515 483 | 0 484 | 0.01293887867686162 485 | 3.64654130883773e-14 486 | 3.303592672891557e-14 487 | 2.501294835087123e-13 488 | 9.043300576578818e-14 489 | 1.665519256445485e-13 490 | 6.299923613303121e-13 491 | 4.644802538255621e-13 492 | 2.9837822186614e-13 493 | 7.189653920866689e-13 494 | 9.422850650304828e-13 495 | 9.58798947370524e-13 496 | 8.367390714757451e-13 497 | 7.043469532508356e-13 498 | 0.9999939192512389 499 | 0.9999969490171112 500 | 0.999999478518122 501 | 0.9999999999997565 502 | 0.9999999999995677 503 | 0.9999999999996901 504 | 0.9999999999993665 505 | 0.9999999999995038 506 | 0.9999999999994209 507 | 0.999999975720718 508 | 0.9999999999997999 509 | 2.112343016469597e-13 510 | 3.930187032296392e-13 511 | 0.9999999999999042 512 | 0.9999999999999418 513 | 1 514 | 0.9999999999998279 515 | 0.9999999999998044 516 | 0.9999999999992139 517 | 0.9999999978972394 518 | 0.9999999999999092 519 | 2.979648988346679e-13 520 | 4.371848394222645e-13 521 | 4.968897647793701e-13 522 | 6.989671393011431e-13 523 | 0.9999999999986189 524 | 0.9999999999992967 525 | 6.724881800242647e-13 526 | 9.500263664181636e-13 527 | 0.999999999999487 528 | 0.9999999999992846 529 | 9.231595609826822e-13 530 | 1.251549333147438e-12 531 | 0.9999999999997835 532 | 0.999999999999423 533 | 0.9999999999997328 534 | 0.9999999999996469 535 | 0.9999999999993 536 | 0.9996807604205415 537 | 8.326491827443122e-13 538 | 1.075155948429862e-12 539 | 1.094497798978122e-12 540 | 1.114304950741408e-12 541 | 1.181388463872524e-12 542 | 1.32248516563154e-12 543 | 1.216352161401117e-12 544 | 0.9999999999991606 545 | 0.9999999999999529 546 | 0.9999999999993244 547 | 0.9999999999990602 548 | 0.9999999999987043 549 | 9.186445254227547e-13 550 | 1.308170297697426e-12 551 | 1.328837125454414e-12 552 | 0.9999999999994141 553 | 0.9999999999993412 554 | 0.9999999999996753 555 | 0.999999999999637 556 | 0.9999999999989156 557 | 0.9999999999987704 558 | 0.9999999999987684 559 | 0.9999999999986903 560 | 0.9999999999991162 561 | 0.9999999999990249 562 | 0.999999999999143 563 | 0.9999999999983865 564 | 1.174785123881669e-12 565 | 0.9999999999987453 566 | 0.9999999999990364 567 | 0.9999999999991684 568 | 0.6967387041910494 569 | 0.8211205027395425 570 | 0.3512543470103556 571 | 0.1086131279234997 572 | 0.04475539984275143 573 | 0.003486163084260526 574 | 0.06157667259894199 575 | 0.1567791169041051 576 | 0.03499803526984367 577 | 0 578 | 1.352874877429962e-13 579 | 2.655521244026422e-13 580 | 2.558093901702642e-13 581 | 7.842901895580053e-14 582 | 6.228150749435307e-13 583 | 1.921120995929305e-13 584 | 3.522324291580556e-13 585 | 1.070079693693524e-13 586 | 4.593135570072358e-14 587 | 0 588 | 9.99750710102853e-14 589 | 0 590 | 1.085199026229562e-12 591 | 1.187823536766605e-12 592 | 1.347383301874973e-12 593 | 1.181342680102499e-12 594 | 1.242806662867366e-12 595 | 1.248131507052985e-12 596 | 0.02956771419432947 597 | 0.3201438184519442 598 | 0.5726093276897267 599 | 0.5972911048838759 600 | 0.5075808790447645 601 | 0.44127785245103 602 | 0.9546762947207132 603 | 0.8268100429203102 604 | 0.8650457272926213 605 | 0.8366845470306292 606 | 0.9988227158012866 607 | 0.9991310279287104 608 | 1 609 | 0.996380302188869 610 | 6.527487117354495e-14 611 | 0.9999987871390372 612 | 0.9999996763169329 613 | 0.9999999125825376 614 | 5.678906412179645e-13 615 | 0.9999999999990684 616 | 0.9999999999991197 617 | 5.368119726708693e-13 618 | 0.9999999999987399 619 | 0.9999999999983327 620 | 0.9999999999990983 621 | 0.9999999999993139 622 | 0.9999999999993734 623 | 0.999999999999258 624 | 0.1522709745662694 625 | 0.28994422145057 626 | 0.01287824911036385 627 | 2.498338577617952e-26 628 | 2.083181086961504e-13 629 | 7.900293010025606e-14 630 | 1.353052120542362e-12 631 | 0.4262849356198842 632 | 0.9999997026760267 633 | 0.9999999999991181 634 | 0.9999999999991369 635 | 0.9999999999995582 636 | 0.9999999999995052 637 | 5.750730790467018e-14 638 | 3.616656772605256e-14 639 | 9.281071437637853e-14 640 | 1.227836335392789e-13 641 | 7.83220934633881e-13 642 | 8.519399938391212e-13 643 | 8.484942952287748e-13 644 | 8.134254100663787e-13 645 | 4.695808405269599e-13 646 | 1.643513420923178e-13 647 | 2.271914498982041e-13 648 | 3.479467737380572e-13 649 | 3.647903875859945e-13 650 | 3.665479396278763e-13 651 | 3.599092642404584e-13 652 | 3.070915444300041e-13 653 | 5.41628026405647e-14 654 | 1.796547526608817e-23 655 | 2.244267818063447e-24 656 | 4.606815263067213e-14 657 | 3.977875182369656e-13 658 | 1.016426825094759e-12 659 | 1.11162515628528e-12 660 | 1.202671207318565e-12 661 | 1.284929243623334e-12 662 | 1.289639331517192e-12 663 | 1.369475089180733e-12 664 | 1.74161491255328e-12 665 | 2.522514120919391e-12 666 | 2.79597656099304e-12 667 | 3.029588639068635e-12 668 | 3.186657865144528e-12 669 | 3.221501598362968e-12 670 | 3.302765016840234e-12 671 | 3.300672566482975e-12 672 | 3.290785316109275e-12 673 | 3.378205328517114e-12 674 | 4.003799112611006e-12 675 | 4.078939588416973e-12 676 | 4.162174847399976e-12 677 | 4.20593957199834e-12 678 | 4.206281467608779e-12 679 | 4.202847859662259e-12 680 | 3.648184958063256e-12 681 | 3.791911061152823e-12 682 | 3.793724941344382e-12 683 | 3.793076554334913e-12 684 | 3.763639975428471e-12 685 | 3.750255050897777e-12 686 | 3.498785710670405e-12 687 | 2.608387719557165e-12 688 | 1.688894528332719e-12 689 | 1.269964624440851e-12 690 | 8.840939491817492e-13 691 | 7.926297552039164e-13 692 | 7.550510528878833e-13 693 | 7.280855837635675e-13 694 | 6.693832059136195e-13 695 | 6.087415699475405e-13 696 | 5.088669327476909e-13 697 | 4.61331648254893e-13 698 | 7.455029301844786e-13 699 | 8.114116022101778e-13 700 | 1.034882222999503e-12 701 | 1.043199756062072e-12 702 | 1.04274848980952e-12 703 | 1.026444585046855e-12 704 | 8.958456408423881e-13 705 | 1.620438248344099e-13 706 | 8.969874418050144e-19 707 | 3.716809481655276e-07 708 | 9.401102287045667e-06 709 | 0.01693793959303039 710 | 0.1841621052062564 711 | 0.431150707067663 712 | 0.8235415579339667 713 | 0.9734985432396026 714 | 0.99999999999971 715 | 0.9999999999996033 716 | 0.999999999999604 717 | 0.9999999999996871 718 | 0.999999999999696 719 | 0.9999999999997331 720 | 0.9999999999997917 721 | 0.9999999999996682 722 | 0.9999999999996703 723 | 0.9999999999996935 724 | 0.9999999999998 725 | 0.9999999999996718 726 | 0.9999999999995074 727 | 0.999999999999414 728 | 0.9999999999994982 729 | 0.98552480145065 730 | 0.9681974761293812 731 | 0.9234072279068107 732 | 0.8696139404489345 733 | 0.6618777954890627 734 | 0.4571006041136239 735 | 0.2563644457060982 736 | 0.1659262394180901 737 | 0.1361084213166269 738 | 0.08974745965383356 739 | 0.05095970252469013 740 | 0.008712156187864577 741 | 0.005455224767036844 742 | 7.933016380628687e-24 743 | 1.270779918389185e-21 744 | 8.241355087743269e-23 745 | 7.663449018856227e-05 746 | 7.310442029104211e-15 747 | 5.181125876739966e-14 748 | 8.659191802400256e-14 749 | 9.806282570847276e-14 750 | 9.836227981983802e-14 751 | 4.728861959001848e-14 752 | 1.863981812243071e-13 753 | 4.343852060278434e-13 754 | 6.136015814942149e-13 755 | 8.144548255170907e-14 756 | 0.005659217920366329 757 | 9.370905530517749e-14 758 | 9.409130650384531e-14 759 | 4.192766709842311e-12 760 | 9.648100269895369e-14 761 | 8.710035595078861e-14 762 | 1.073957140750885e-12 763 | 1.308109908202831e-12 764 | 2.717352834366565e-12 765 | 3.792064099098894e-12 766 | 8.205832510595867e-07 767 | 0.00235355772546612 768 | 0.009546300230494761 769 | 3.728753121292112e-12 770 | 3.781094059434441e-12 771 | 3.772032960902119e-12 772 | 3.781389131108254e-12 773 | 3.785011410014386e-12 774 | 3.777391800560474e-12 775 | 2.350939684468904e-06 776 | 0.9999999999997309 777 | 4.203373199821846e-12 778 | 7.548235579677349e-14 779 | 1.250729013094153e-12 780 | 0.9999999999996975 781 | 4.083395796363261e-12 782 | 6.943763231480901e-14 783 | 1.286953024170323e-12 784 | 4.167337404097999e-12 785 | 2.78970174249311e-14 786 | 1.304496029702636e-12 787 | 4.191061996195395e-12 788 | 3.276864046778008e-12 789 | 6.654037319429225e-13 790 | 1.24514686234479e-07 791 | 1.254671541568641e-12 792 | 1.32405754737418e-12 793 | 4.177105523188244e-12 794 | 3.294203156082613e-12 795 | 1.19091309046166e-12 796 | 3.284289460692922e-12 797 | 3.582487086451199e-13 798 | 3.098151808765622e-12 799 | 0.9899896553095017 800 | 1.012165608206983e-12 801 | 2.312066628001745e-12 802 | 3.812458352740469e-24 803 | 0.001248520587754952 804 | 4.180699195019947e-05 805 | 0.0294587362441203 806 | 3.74983101897891e-12 807 | 0.0004803829082312669 808 | 1.15014910791828e-12 809 | 2.922210419986246e-12 810 | 3.233080478441613e-12 811 | 0.00463928218245719 812 | 0.01962200837786236 813 | 0.001558947030654382 814 | 2.95633224242126e-12 815 | 3.048516209419562e-12 816 | 3.237218472926901e-12 817 | 3.196841872726873e-12 818 | 8.398798752353927e-13 819 | 4.128459870473882e-12 820 | 2.95280242562484e-13 821 | 1.049340807896241e-23 822 | 9.850464833770581e-13 823 | 3.264861091665395e-12 824 | 0.006869111769981916 825 | 0.001112721681016249 826 | 0.0007255793813146178 827 | 1.284051530926863e-12 828 | 7.213698127448438e-13 829 | 0.9999999999998153 830 | 8.478148533392151e-13 831 | 1.543548155969712e-12 832 | 3.686762932499876e-12 833 | 0.04494975942370562 834 | 3.110957264585446e-12 835 | 3.498314278720539e-12 836 | 4.012791055812624e-12 837 | 3.094959058443098e-13 838 | 1.93251507029141e-13 839 | 0.01827813173088523 840 | 0.0004261843259777213 841 | 0.9999999999997766 842 | 6.380149784497683e-13 843 | 0.9378629434386228 844 | 1.922873853484415e-12 845 | 1.358319044621467e-12 846 | 0.000150364744716001 847 | 3.870756076840574e-23 848 | 2.541633369731089e-12 849 | 3.637446164625657e-12 850 | 0.1480034774581892 851 | 1.632022121582176e-13 852 | 0.9999999999999585 853 | 1.877054873538337e-12 854 | 6.474929704373388e-14 855 | 2.447044375890726e-13 856 | 1.635785666977422e-14 857 | 0.9998997814808362 858 | 0.9999999999998272 859 | 9.455411473296565e-13 860 | 3.806928393063589e-12 861 | 5.745726107226042e-13 862 | 0.9065166119372515 863 | 0.9801401226794343 864 | 3.697263309901206e-05 865 | 1.860085024347684e-13 866 | 0.1691491596336942 867 | 0.9974559279083148 868 | 0.9999999999996555 869 | 3.932450360691205e-12 870 | 0.8223532682686743 871 | 1.424670914284331e-24 872 | 0.01615173724051042 873 | 3.105702965332934e-13 874 | 0.9999999999996938 875 | 0.9999999999997761 876 | 4.107222461703079e-12 877 | 0.7727213889032173 878 | 0.8815503902181989 879 | 0.001663158910169582 880 | 4.844367123278573e-14 881 | 4.050827751549555e-12 882 | 0.916114506694652 883 | 0.007640994582910744 884 | 0.004692180725688405 885 | 5.27724707633411e-13 886 | 0.9999999999996896 887 | 6.414190008014817e-13 888 | 3.932001281097021e-12 889 | 3.345602879691813e-05 890 | 4.119327776913787e-06 891 | 3.434679609109523e-12 892 | 0.9999999999997998 893 | 1 894 | 0.9999999999999346 895 | 0.9999999999997801 896 | 0.9999999999997154 897 | 0.9999999999996673 898 | 1.667008166039952e-12 899 | 1.033061461939556e-13 900 | 0.9999749803762719 901 | 0.9999999999999779 902 | 4.109458879140106e-12 903 | 0.7078424894621903 904 | 0.8415711812458055 905 | 5.154792526842751e-14 906 | 6.92361310709693e-13 907 | 7.520578132008374e-13 908 | 0.9999999999995171 909 | 7.810604639822606e-13 910 | 1.894517680601224e-12 911 | 1.559873135470977e-12 912 | 1.954361777771072e-12 913 | 1.627832053722468e-12 914 | 1.001398789574372e-12 915 | 1.246933797154829e-12 916 | 1.382368242982773e-12 917 | 1.585646835415446e-12 918 | 1.202994652825098e-12 919 | 9.537073975352933e-13 920 | 1.733812042173675e-12 921 | 1.229558599935666e-12 922 | 1.069478068362613e-12 923 | 7.439060835855086e-13 924 | 6.192875718317233e-13 925 | 3.041356477184656e-13 926 | 0.9996131738452906 927 | 0.9999999999998312 928 | 0.7576732811592107 929 | 6.874865011132391e-26 930 | 0.04622831917778861 931 | 6.626062497711497e-13 932 | 0.9999999999996322 933 | 0.9999999999997125 934 | 9.208194678047977e-13 935 | 6.529433517193858e-13 936 | 6.78297519117726e-13 937 | 1.341138154163212e-13 938 | 0.9984692971336424 939 | 0.9999999999998708 940 | 0.9999999999999882 941 | 1.202623643717224e-13 942 | 0.005821141502838357 943 | 0.02170983047832099 944 | 0.9999999999994277 945 | 0.9999999999997833 946 | 0.9999999999998982 947 | 1.019055767848853e-12 948 | 7.51982207163944e-13 949 | 9.09132166564795e-13 950 | 9.57526915789616e-13 951 | 5.888311033268405e-13 952 | 3.290372937965263e-13 953 | 0.9964775016934486 954 | 0.9999999999998525 955 | 0.9999999999998436 956 | 0.9972391122468769 957 | 3.683772539328661e-13 958 | 1.119792024579867e-13 959 | 7.297250479770104e-23 960 | 0.0846470028949366 961 | 0.9999999999996073 962 | 0.9999999999996637 963 | 0.9999999999996694 964 | 1.130070694511398e-12 965 | 8.873339790185442e-13 966 | 6.845683388277069e-13 967 | 4.262229221054389e-13 968 | 0.9999999999998126 969 | 0.9998534754292308 970 | 0.999889989665492 971 | 0.998416203618986 972 | 0.9909903135867714 973 | 0.05232458350580696 974 | 0.04354583425397927 975 | 0.1701147962759975 976 | 0.02895326689993784 977 | 0.06350781637892473 978 | 0.09844149692622131 979 | 0.1515775725113891 980 | 0.1051863194822197 981 | 0.02710232434264645 982 | 0.9999999999994624 983 | 0.9999999999995239 984 | 0.9999999999995931 985 | 0.9999999999999147 986 | 0.9973415437226066 987 | 0.9999999999999953 988 | 1 989 | 0.04604955727562527 990 | 0.08101294199949717 991 | 0.1269876816140177 992 | 0.9922137390693799 993 | 0.9999999999999658 994 | 0.9999999999999398 995 | 0.9999999999999906 996 | 1 997 | 0.9999999999999551 998 | 1 999 | 0.9999999999998885 1000 | 0.9999999999998261 1001 | 0.9999999999998143 1002 | 0.05633185714408339 1003 | 0.1110573118037674 1004 | 0.1060835636547805 1005 | 0.2515922898866463 1006 | 0.1558872130952454 1007 | 1 1008 | 0.9994965462429993 1009 | 0.9919164722692989 1010 | 0.9999999999997657 1011 | 0.9999999999999051 1012 | 0.9999999999997066 1013 | 0.9999999999997241 1014 | 0.9999999999997575 1015 | 0.181686315672511 1016 | 0.999140282336226 1017 | 0.1991881618564379 1018 | 3.844976839554841e-13 1019 | 5.437727460235457e-13 1020 | 2.625564688767041e-12 1021 | 2.338943352873445e-12 1022 | 2.235278523848987e-12 1023 | 0.9999999999998471 1024 | 8.727177167676397e-13 1025 | 4.650772889847113e-13 1026 | 9.183630738865982e-13 1027 | 7.537235369018942e-13 1028 | 9.395695757572038e-13 1029 | 4.91238633019713e-13 1030 | 0.956702379949969 1031 | 1.940093241206707e-13 1032 | 3.320906026011231e-13 1033 | 0.6922768402483652 1034 | 0.9999999999996415 1035 | 3.221161846470008e-12 1036 | 1.523827837449208e-12 1037 | 1.402700484201924e-12 1038 | 9.602723853224059e-13 1039 | 1.128535632930742e-12 1040 | 4.829771098883581e-13 1041 | 5.506947246194275e-13 1042 | 2.008774748940316e-13 1043 | 3.186631362849787e-14 1044 | 4.292943151881404e-13 1045 | 2.58341822429799e-13 1046 | 5.493918210965866e-13 1047 | 1.627339469837369e-13 1048 | 3.721078537186155e-14 1049 | 0 1050 | 2.583502007834153e-13 1051 | 5.840535053426759e-14 1052 | 4.38654411331902e-14 1053 | 2.212403117220233e-26 1054 | 0.0570854573578127 1055 | 0.001822560167069046 1056 | 0.02237562173228956 1057 | 0 1058 | 0.0003191628322139489 1059 | 4.837897640879984e-13 1060 | 0.03716654371987475 1061 | 1.568323429405683e-13 1062 | 6.648114227426146e-14 1063 | 0.001067790168209224 1064 | 4.238988383014296e-13 1065 | 7.108789556211337e-13 1066 | 7.031782531209658e-13 1067 | 0.4740660932620164 1068 | 1.27290094701872e-13 1069 | 2.977634905659058e-13 1070 | 2.120319266192108e-14 1071 | 1.474737876243492e-24 1072 | 3.861840042416942e-13 1073 | 7.468995943047892e-13 1074 | 0.9771216624745725 1075 | 0.2768318231719843 1076 | 2.205531153280323e-14 1077 | 0 1078 | 9.026876180955604e-23 1079 | 2.647861068729155e-13 1080 | 0.9107066819930897 1081 | 6.591465975388654e-14 1082 | 1.383737298802428e-13 1083 | 3.054165246077789e-06 1084 | 4.036023566275195e-13 1085 | 1.443360369749105e-13 1086 | 4.616479382713377e-13 1087 | 3.911833802479853e-13 1088 | 4.936886347536916e-13 1089 | 3.194589827480077e-13 1090 | 6.225947316726618e-13 1091 | 1.796607479160535e-14 1092 | 5.38893356842829e-13 1093 | 9.860888882238371e-14 1094 | 4.072416331942643e-13 1095 | 7.40848672822868e-13 1096 | 1 1097 | 0.9956475553335529 1098 | 2.762699586023923e-13 1099 | 2.203712058040068e-13 1100 | 7.993419339768502e-20 1101 | 2.162937210123765e-13 1102 | 6.928389734572247e-13 1103 | 0.1372494872895752 1104 | 0.8909719728856322 1105 | 0.913862380212968 1106 | 1.999764805826645e-06 1107 | 5.006958785512379e-20 1108 | 7.482799005004814e-08 1109 | 2.94862849412064e-14 1110 | 8.776334247952955e-15 1111 | 1.956429549926338e-13 1112 | 1.67673706412582e-15 1113 | 5.032752304653564e-19 1114 | 7.325355652322075e-13 1115 | 1.651763801928845e-14 1116 | 2.157663827141478e-27 1117 | 0.09433635056297807 1118 | 0.1272112688313767 1119 | 0.4557048181651311 1120 | 0.4201547531830852 1121 | 0.9866533099287503 1122 | 1 1123 | 0.9870611213230572 1124 | 0.9876861303922402 1125 | 0.9626906294703393 1126 | 0.9395510773465102 1127 | 0.9529612046378469 1128 | 0.8023813458975256 1129 | 0.7654336005062895 1130 | 0.8796896416945226 1131 | 0.8733679630842496 1132 | 0.8151532654032029 1133 | 0.6271345926568621 1134 | 0.7390088869851423 1135 | 0.7125583587057912 1136 | 0.6043539629168929 1137 | 6.080748683947743e-06 1138 | 3.05098283663843e-06 1139 | 5.214818592411399e-07 1140 | 2.434075335429034e-13 1141 | 3.919812605319472e-13 1142 | 2.218720187527313e-13 1143 | 6.335406772284371e-13 1144 | 4.961012756298241e-13 1145 | 4.870863452829798e-13 1146 | 2.427916567834402e-08 1147 | 6.563556119257705e-14 1148 | 0.8733124708847082 1149 | 0.7126307458353308 1150 | 6.418677045520708e-14 1151 | 2.792940578748851e-14 1152 | 0 1153 | 7.911029998494052e-14 1154 | 1.13305903139073e-13 1155 | 5.592996746252154e-13 1156 | 2.102672719178138e-09 1157 | 1.950720683633467e-14 1158 | 0.5993638740456366 1159 | 0.3539856805708306 1160 | 0.5420966130607021 1161 | 0.4239515562151118 1162 | 6.87801070743697e-13 1163 | 6.303049902852319e-13 1164 | 0.2851015601684238 1165 | 0.5140778424132082 1166 | 2.540704062883626e-13 1167 | 7.046998491164605e-13 1168 | 0.3757166276865743 1169 | 0.5247508088532443 1170 | 1.049003981623692e-13 1171 | 2.843678810400508e-13 1172 | 1.319316123103688e-13 1173 | 1.678730479546365e-13 1174 | 7.000508023553358e-13 1175 | 7.056634198278129e-13 1176 | 0.2729735514215716 1177 | 0.321744959878935 1178 | 0.5657389398630644 1179 | 0.432320284335631 1180 | 0.612354780690115 1181 | 0.5580065147765078 1182 | 0.6423519868819502 1183 | 4.169787280666512e-13 1184 | 2.491175349488531e-14 1185 | 3.354599982743244e-13 1186 | 4.679651449068275e-13 1187 | 6.440321219763949e-13 1188 | 0.232126019614117 1189 | 0.3849109493775846 1190 | 0.4937520611746682 1191 | 2.896984112642652e-13 1192 | 3.251688818630831e-13 1193 | 1.599790388776682e-13 1194 | 1.864402894596881e-13 1195 | 5.3826421023598e-13 1196 | 6.091799712278724e-13 1197 | 6.086595211704836e-13 1198 | 6.454403939063175e-13 1199 | 4.35497260372968e-13 1200 | 4.807487669335261e-13 1201 | 4.297418527615462e-13 1202 | 8.028858774160206e-13 1203 | 0.3695932834376259 1204 | 6.185752381742716e-13 1205 | 4.789672009476251e-13 1206 | 4.439193890841228e-13 1207 | 1.879714620117769e-12 1208 | 1.283873226391697e-12 1209 | 8.12926755137495e-13 1210 | 3.567760445813201e-13 1211 | 1.546320890801152e-13 1212 | 2.248501018129421e-26 1213 | 1.023970101221204e-13 1214 | 3.483629911939017e-13 1215 | 9.025984058832994e-14 1216 | 0 1217 | 0.08262725237344182 1218 | 0.184186569449361 1219 | 0.347517931814391 1220 | 0.02415591706095433 1221 | 0.1286068587323735 1222 | 0.9717285632320427 1223 | 0.9538131779794552 1224 | 0.9999999999997855 1225 | 0.9999999999999079 1226 | 1 1227 | 0.9999999999998002 1228 | 1 1229 | 0.1728072947025255 1230 | 0.2070966827393138 1231 | 0.3501686269181987 1232 | 0.2463147272465179 1233 | 0.304462277639824 1234 | 0.2604658527977097 1235 | 8.672446223211328e-14 1236 | 0.6798561815479052 1237 | 0.4273906723101422 1238 | 8.018167405420059e-13 1239 | 6.939378100489693e-13 1240 | 4.127399646603768e-13 1241 | 0.04532370527926987 1242 | 0.1731899570795747 1243 | 8.094563226289305e-13 1244 | 7.749853908170649e-13 1245 | 5.617043129830619e-14 1246 | 1.413970460962946e-14 1247 | 0 1248 | 7.395779196728692e-13 1249 | 0.7747511725016532 1250 | 1.21286088689087e-06 1251 | 3.236830143573824e-07 1252 | 8.741738154709155e-08 1253 | 0.7079952262401166 1254 | 5.574043027781347e-13 1255 | 6.400797398114873e-13 1256 | 0.1766388045972881 1257 | 6.273111353639184e-13 1258 | 8.285819475856204e-13 1259 | 4.752731928510183e-13 1260 | 3.506962261729e-13 1261 | 3.571254104809467e-13 1262 | 4.649369333148406e-13 1263 | 1.826068020068499e-13 1264 | 4.595244422740818e-13 1265 | 1.160895320164531e-26 1266 | 0.01859241787277454 1267 | 0.9810858176277256 1268 | 0.9999999999998479 1269 | 0.4056300991566559 1270 | 8.639031512670646e-13 1271 | 2.973239732878331e-07 1272 | 5.515704854792119e-13 1273 | 4.922838152594227e-13 1274 | 2.462155611171882e-13 1275 | 3.087196105580436e-13 1276 | 0.9999999999998851 1277 | 0.9999999999999277 1278 | 0.9999999999998146 1279 | 0.9999999999997519 1280 | 0.9999999999987318 1281 | 0.9999999999986032 1282 | 0.99999999999861 1283 | 0.9999999999986774 1284 | 0.9999999999993224 1285 | 0.9999999999998357 1286 | 0.9999999999997546 1287 | 0.9999999999995564 1288 | 0.9999999999995247 1289 | 0.9999999999995222 1290 | 0.9999999999995369 1291 | 0.9999999999996457 1292 | 0.999867893836603 1293 | 0.997989835166144 1294 | 0.9955410580377151 1295 | 0.9788428560940908 1296 | 0.9254926800964802 1297 | 0.8150711136306905 1298 | 0.7973684218829111 1299 | 0.781448095687042 1300 | 0.7653779843494178 1301 | 0.7641770852115169 1302 | 0.7398070330214819 1303 | 0.6446829556711138 1304 | 0.5019886348478885 1305 | 0.4752629451773717 1306 | 0.4587609391074958 1307 | 0.450294810374208 1308 | 0.4485774107771141 1309 | 0.4445069247083536 1310 | 0.4444216516505545 1311 | 0.4434301823793629 1312 | 0.4309206642505254 1313 | 0.4083740435731625 1314 | 0.4069309259950101 1315 | 0.4050400351743096 1316 | 0.4043904433799453 1317 | 0.4043853252019078 1318 | 0.4044224406611805 1319 | 0.4031868922836301 1320 | 0.3902372120240957 1321 | 0.3901740969560244 1322 | 0.3901551508940642 1323 | 0.3899135189183654 1324 | 0.3898931256632889 1325 | 0.3908136235044168 1326 | 0.3644813772407334 1327 | 0.2490857206506976 1328 | 0.1639613370435782 1329 | 0.05742749344694812 1330 | 0.02658781977605179 1331 | 0.008700279655554298 1332 | 7.751604604098822e-05 1333 | 1.460194282107043e-13 1334 | 3.126660105163115e-13 1335 | 4.107020655257615e-13 1336 | 4.458796822130908e-13 1337 | 7.638765780027815e-13 1338 | 8.28329890391037e-13 1339 | 1.044889152315586e-12 1340 | 1.05285183738984e-12 1341 | 1.052140045150407e-12 1342 | 1.035649405242528e-12 1343 | 9.038679797736985e-13 1344 | 1.945216906122612e-13 1345 | 1.4100107029114e-13 1346 | 8.515663308873019e-14 1347 | 7.713040457905667e-14 1348 | 1.001180201592911e-13 1349 | 1.438610190386e-13 1350 | 1.66398890315249e-13 1351 | 1.465361387886657e-13 1352 | 1.192665581615845e-13 1353 | 1.583437929143971e-13 1354 | 1.904935587761912e-13 1355 | 1.916666503768752e-13 1356 | 1.588527970520349e-13 1357 | 1.544288058070249e-13 1358 | 1.335210437592553e-13 1359 | 1.040673794725692e-13 1360 | 1.658993241790343e-13 1361 | 1.648618861917224e-13 1362 | 1.531342979867686e-13 1363 | 1.006147660395403e-13 1364 | 1.637150581329539e-13 1365 | 2.381511774758702e-13 1366 | 2.26902883729428e-13 1367 | 1.285888452591057e-13 1368 | 0.0144751985490148 1369 | 0.03180252387021068 1370 | 0.07659277209256636 1371 | 0.1303860595502514 1372 | 0.3381222045097121 1373 | 0.5428993958850098 1374 | 0.7436355542926337 1375 | 0.8340737605808177 1376 | 0.8638915786823796 1377 | 0.9102525403454155 1378 | 0.9490402974748603 1379 | 0.9912878438120869 1380 | 0.9945447752329182 1381 | 0.9999999999997601 1382 | 0.9999999999997445 1383 | 0.9999999999997448 1384 | 0.9999233655096382 1385 | 0.9999999999997961 1386 | 0.9999999999997226 1387 | 0.9999999999996665 1388 | 0.9999999999996474 1389 | 0.9999999999996468 1390 | 0.9999999999997817 1391 | 0.9999999999996745 1392 | 0.9999999999993283 1393 | 0.9999999999990344 1394 | 0.9999999999996819 1395 | 0.9943407820796059 1396 | 0.9999999999996561 1397 | 0.9999999999996541 1398 | 0.4045695386903365 1399 | 0.9999999999996504 1400 | 0.9999999999996675 1401 | 0.802602315615832 1402 | 0.7582907724049985 1403 | 0.4744818268346925 1404 | 0.3902052279847092 1405 | 0.9982434186345263 1406 | 0.9976464422744858 1407 | 0.9904536997694769 1408 | 0.3923923047501131 1409 | 0.3900666466837113 1410 | 0.3908511284577095 1411 | 0.3902355888580783 1412 | 0.3904431513739323 1413 | 0.3905213966151217 1414 | 0.9999976490600821 1415 | 1.345031327162476e-13 1416 | 0.40442038131031 1417 | 0.9999999999996866 1418 | 0.7722451119209647 1419 | 1.512176259196409e-13 1420 | 0.4055418808857922 1421 | 0.9999999999997035 1422 | 0.7641594865720944 1423 | 0.4047993130735774 1424 | 0.9999999999997741 1425 | 0.7575068995373732 1426 | 0.4045532052560715 1427 | 0.4456135834692547 1428 | 0.8805747425682884 1429 | 0.9999998754850725 1430 | 0.7701811268520956 1431 | 0.7446619735441287 1432 | 0.4047433675544976 1433 | 0.4448098978243928 1434 | 0.7813091372932462 1435 | 0.4447055477091007 1436 | 0.9999999999995397 1437 | 0.4491862160491744 1438 | 0.01001034469021514 1439 | 1.022000886293713e-12 1440 | 0.5036096314374945 1441 | 0.9997440593713197 1442 | 0.9987514794122451 1443 | 0.9965388248135233 1444 | 0.9705412637556484 1445 | 0.3908022163049387 1446 | 0.9995196170916196 1447 | 0.7822998018412006 1448 | 0.463911443545548 1449 | 0.4465551643942341 1450 | 0.9953607178175428 1451 | 0.980377991622014 1452 | 0.9984410529692557 1453 | 0.4401913081794265 1454 | 0.4465124486059506 1455 | 0.4322287195846982 1456 | 0.4417227312223957 1457 | 0.9999999999986261 1458 | 0.4051882373195353 1459 | 0.9999999999996488 1460 | 0.9999999999999218 1461 | 0.8151873823978645 1462 | 0.4438050367470026 1463 | 0.9931308882300182 1464 | 0.9986385403271609 1465 | 0.9992744206185726 1466 | 0.7343015683884591 1467 | 7.372882951580334e-13 1468 | 9.251840855217852e-14 1469 | 0.84485596874491 1470 | 0.6906678250773687 1471 | 0.3904129233413192 1472 | 0.9550502405759391 1473 | 0.4144392735044222 1474 | 0.4151745356381973 1475 | 0.4066833639444283 1476 | 0.9999999999996315 1477 | 0.9999999999998068 1478 | 0.9817218682690519 1479 | 0.9995738156739962 1480 | 1.116741599304975e-13 1481 | 0.8768239033997638 1482 | 0.06213705656088294 1483 | 0.5922920065475462 1484 | 0.226997479155032 1485 | 0.9996411214136149 1486 | 0.9866568123300545 1487 | 0.4564615713962176 1488 | 0.3921842873541149 1489 | 0.8519965225408426 1490 | 0.9999999999998369 1491 | 2.095912556151944e-14 1492 | 0.447227430029181 1493 | 0.9999822290143011 1494 | 0.9999999999997393 1495 | 0.9999999999999837 1496 | 0.0001002185188378959 1497 | 7.684902445998014e-14 1498 | 9.582755483731572e-13 1499 | 0.4129369377128854 1500 | 0.8941405281859547 1501 | 0.09348338806207326 1502 | 0.01985987732031142 1503 | 0.9956054952708747 1504 | 0.9570761520218366 1505 | 6.443367969022508e-14 1506 | 0.002544072091378426 1507 | 1.644421919219292e-13 1508 | 0.409382063873013 1509 | 0.1776467317305112 1510 | 0.9928655769472545 1511 | 0.9838482627594728 1512 | 0.9344448852371537 1513 | 1.491249598583518e-13 1514 | 1.117219050417262e-13 1515 | 0.4061911520343174 1516 | 0.2272786110957331 1517 | 0.118449609781103 1518 | 0.9977921688561816 1519 | 0.9747298209586129 1520 | 0.4073110049600404 1521 | 0.08388549330490772 1522 | 0.9923590054170892 1523 | 0.9953078192743117 1524 | 0.9999999999991954 1525 | 1.119613079247316e-13 1526 | 0.03159937815834626 1527 | 0.4062768030354261 1528 | 0.9999665439710677 1529 | 0.9999958806722232 1530 | 0.3955886103336518 1531 | 1.005974037953721e-13 1532 | 0 1533 | 3.285926483003597e-14 1534 | 1.098984856248735e-13 1535 | 1.395993192138169e-13 1536 | 1.649228906085306e-13 1537 | 0.5626468442189435 1538 | 0.999999999999809 1539 | 2.501962361021911e-05 1540 | 6.077640274064903e-15 1541 | 0.4058372528632975 1542 | 0.2921575105367117 1543 | 0.1584288187533288 1544 | 0.9842913325548746 1545 | 0.9999999999989075 1546 | 0.9999999999987919 1547 | 1.535056620663527e-13 1548 | 0.03937224468254174 1549 | 0.5610592845617358 1550 | 0.6381829760971333 1551 | 0.5057312964393119 1552 | 0.4873382767638735 1553 | 0.6438133285955739 1554 | 0.3307847379671938 1555 | 0.5572542846156966 1556 | 0.4242434662524908 1557 | 0.6776507922045513 1558 | 0.4732639603697734 1559 | 0.3255841540396003 1560 | 0.4310442417576316 1561 | 0.539000988817441 1562 | 0.2749485384113185 1563 | 0.6438656580258062 1564 | 0.9999999999995401 1565 | 0.0003868261544455098 1566 | 8.778613367356869e-14 1567 | 0.2423267188397333 1568 | 0.9975505040774518 1569 | 0.9537716808220196 1570 | 0.9999999999989555 1571 | 1.168045921811033e-14 1572 | 9.719051592658225e-15 1573 | 0.08006446015905293 1574 | 0.01145678098816412 1575 | 0.8232598555777287 1576 | 0.9999999999998415 1577 | 0.001530702866177621 1578 | 1.291357264673034e-13 1579 | 3.362612614498243e-25 1580 | 0.9667284518510778 1581 | 0.9941788584971506 1582 | 0.9782901695216097 1583 | 2.580164934476759e-13 1584 | 2.621952673386656e-24 1585 | 2.656921851349182e-14 1586 | 0.1385419605264543 1587 | 0.02223844088653731 1588 | 0.7471131433538644 1589 | 0.788644530248415 1590 | 0.7799400828237554 1591 | 0.9999999999995609 1592 | 0.003522498306268148 1593 | 1.11801573631757e-13 1594 | 7.08617371423623e-14 1595 | 0.00276088775300952 1596 | 0.9105932163253436 1597 | 0.9652002760075701 1598 | 0.9833544384231973 1599 | 0.9153529971045784 1600 | 1.778596420424384e-13 1601 | 7.542705026947147e-14 1602 | 4.136934997716592e-24 1603 | 0.7386810563979461 1604 | 0.8171058854176755 1605 | 0.8518122272356972 1606 | 0.9102255424869726 1607 | 1.422378746342765e-13 1608 | 4.462760107534399e-14 1609 | 0.0001100103344687645 1610 | 0.00158379638097734 1611 | 0.009009686413029259 1612 | 0.9476754164939423 1613 | 0.9564541657457893 1614 | 0.8298852037233644 1615 | 0.9710467330999275 1616 | 0.9364921836206371 1617 | 0.9015585030733572 1618 | 0.8484224274882962 1619 | 0.8948136805174161 1620 | 0.972897675657298 1621 | 2.227611834932569e-13 1622 | 2.237680850316465e-13 1623 | 5.849041101157429e-14 1624 | 8.518140191126835e-14 1625 | 1.221513162851864e-13 1626 | 1.27623121058052e-24 1627 | 0 1628 | 0.9539504427240695 1629 | 0.9189870579998513 1630 | 0.8730123183851994 1631 | 0.007786260930574786 1632 | 2.502425047094066e-24 1633 | 3.523089769269018e-15 1634 | 6.364081705707147e-23 1635 | 0 1636 | 2.366356305286913e-14 1637 | 0 1638 | 4.35183265794204e-14 1639 | 9.000041121356351e-14 1640 | 8.088239982267292e-14 1641 | 0.9436681428554334 1642 | 0.8889426881953705 1643 | 0.8939164363444584 1644 | 0.7484077101122378 1645 | 0.8441127869039814 1646 | 2.122268709010216e-26 1647 | 1.510710401563378e-26 1648 | 0.00808352773061303 1649 | 1.192007396682911e-13 1650 | 4.78484662091121e-14 1651 | 1.476172449513708e-13 1652 | 1.407454759535467e-13 1653 | 1.235721087004618e-13 1654 | 0.8183136843264891 1655 | 0.0008597176637597134 1656 | 0.8008118381424164 1657 | 1.609279017634173e-13 1658 | 5.596771803620222e-13 1659 | 0.4054983029814546 1660 | 0.4251933527453017 1661 | 0.3808887389626923 1662 | 7.688920354329267e-14 1663 | 8.869053494154126e-13 1664 | 4.688182620587264e-13 1665 | 9.297880030110395e-13 1666 | 7.666795350318953e-13 1667 | 9.486654549793531e-13 1668 | 5.023411741288081e-13 1669 | 0.04329762004959109 1670 | 0.9533868755676406 1671 | 0.9347538574323241 1672 | 1.03383410556657e-13 1673 | 1.779334441216862e-13 1674 | 0.3877090060908886 1675 | 0.67568527423576 1676 | 0.2815798769259104 1677 | 0.2471894343575377 1678 | 0.2029696605586634 1679 | 0.08758466578257901 1680 | 0.1488667495029585 1681 | 0.1932449789673868 1682 | 0.01340382349996012 1683 | 0.21412029840549 1684 | 0.07210175479173124 1685 | 0.3952648754667957 1686 | 0.08311079340783344 1687 | 0.00765069623239766 1688 | 0 1689 | 0.04535967211492004 1690 | 0.06304240384856948 1691 | 0.1027669294858666 1692 | 0.007971669394874131 1693 | 6.162100187726893e-14 1694 | 1.55247595880208e-26 1695 | 7.575053877624039e-14 1696 | 0 1697 | 8.116345287572326e-14 1698 | 0.05061552669656504 1699 | 1.630807173395408e-27 1700 | 0.4700455134713928 1701 | 0.01658836340003336 1702 | 4.819081050647261e-14 1703 | 0.05456164469040856 1704 | 0.09303502726631395 1705 | 0.06177439673264382 1706 | 4.209953759135953e-14 1707 | 0.2956691523853828 1708 | 0.3370617274142428 1709 | 0.4495386173237412 1710 | 3.398686082747782e-14 1711 | 0.02256224827380643 1712 | 0.05368336005473984 1713 | 0.02287833752542738 1714 | 2.071957001456783e-28 1715 | 0.9623135388915061 1716 | 0 1717 | 0.0003834304529274197 1718 | 0.004562264952216611 1719 | 1.799541891942039e-14 1720 | 0.7896429650237758 1721 | 0.01008141289574332 1722 | 7.503598694742701e-14 1723 | 0.01469070526060986 1724 | 0.005923021582838316 1725 | 0.007946068578168172 1726 | 0.0006331543787314477 1727 | 0.003727612640080123 1728 | 0.001931108577401067 1729 | 0.0005422207622578845 1730 | 2.883643844698934e-05 1731 | 0.000860001365009727 1732 | 4.668367705490422e-05 1733 | 7.816300478265687e-08 1734 | 0.001836370382666348 1735 | 0 1736 | 5.457326325470491e-27 1737 | 0.688222345307175 1738 | 0.02443025478228389 1739 | 3.008147432781714e-14 1740 | 3.409296837461183e-24 1741 | 0.003181325214827826 1742 | 0.8627505127104248 1743 | 5.409635905883584e-14 1744 | 9.598448742042931e-14 1745 | 2.166660970645055e-14 1746 | 8.888751706950344e-24 1747 | 3.069112380513379e-14 1748 | 6.340160631179599e-15 1749 | 1.540563881110141e-14 1750 | 4.218281906142224e-14 1751 | 5.52093585191083e-15 1752 | 7.60990318552447e-14 1753 | 0.008951482949595727 1754 | 0.7927400042906561 1755 | 0.9777900310445873 1756 | 0.9056636494369712 1757 | 0.8727887311686073 1758 | 0.5442951818346721 1759 | 0.5798452468168658 1760 | 2.460125969033787e-14 1761 | 0 1762 | 8.112402695783441e-14 1763 | 0.01231386960772331 1764 | 0.03730937052962756 1765 | 0.06044892265323946 1766 | 0.04703879536206253 1767 | 0.1976186541023078 1768 | 0.2345663994930806 1769 | 0.120310358305013 1770 | 0.1266320369154522 1771 | 0.1848467345960783 1772 | 0.3728654073421956 1773 | 0.2609911130138988 1774 | 0.287441641293372 1775 | 0.3956460370824027 1776 | 7.721014863414162e-14 1777 | 5.219280341375254e-14 1778 | 1.898238344877264e-14 1779 | 2.547081662772253e-23 1780 | 4.04361972108167e-14 1781 | 8.796237136416202e-14 1782 | 1.131453707815285e-23 1783 | 2.575412105449744e-23 1784 | 9.202103492773646e-14 1785 | 1.16433437902252e-13 1786 | 1.34410114211961e-13 1787 | 0.1266875291150807 1788 | 0.2873692541642762 1789 | 3.163563023100371e-14 1790 | 3.022875916921468e-14 1791 | 0 1792 | 9.288533979848791e-14 1793 | 8.240717199451674e-14 1794 | 2.26921507289698e-13 1795 | 8.798552124882265e-14 1796 | 7.121797032701447e-14 1797 | 0.4006361259540654 1798 | 0.6460143194287321 1799 | 0.4579033869388009 1800 | 0.5760484437841893 1801 | 6.933211970150545e-13 1802 | 7.299088171133998e-14 1803 | 0.7148984398309037 1804 | 0.4859221575858418 1805 | 2.590415365692163e-13 1806 | 1.074534245452661e-14 1807 | 0.6242833723125026 1808 | 0.4752491911455041 1809 | 1.115758239608596e-13 1810 | 2.925687044388179e-13 1811 | 1.352580070733329e-13 1812 | 1.852469079701768e-13 1813 | 3.860351871196495e-23 1814 | 0.000319239578752775 1815 | 0.7270264485775957 1816 | 0.6782550401199899 1817 | 0.4342610601358409 1818 | 0.5676797156632547 1819 | 0.3876452193087036 1820 | 0.4419934852221699 1821 | 0.3576480131168335 1822 | 4.224719991427148e-13 1823 | 2.209358472630959e-14 1824 | 3.399698646000296e-13 1825 | 4.719551564560405e-13 1826 | 6.516079622224096e-13 1827 | 0.7678739803849645 1828 | 0.6150890506211072 1829 | 0.506247938824003 1830 | 2.961805980533938e-13 1831 | 3.335854611464083e-13 1832 | 1.647948698708662e-13 1833 | 1.765120288615733e-13 1834 | 5.461172233764852e-13 1835 | 6.203156799772572e-13 1836 | 6.230377108192664e-13 1837 | 6.64322932228492e-13 1838 | 4.483279990929145e-13 1839 | 4.944818804952922e-13 1840 | 4.27136390677368e-13 1841 | 8.105756846331725e-13 1842 | 0.6304067165611992 1843 | 6.36112182573826e-13 1844 | 4.845534401352517e-13 1845 | 3.876992674645157e-13 1846 | 0.3032612958070709 1847 | 0.1788794972591736 1848 | 0.6487456529888316 1849 | 0.8913868720761435 1850 | 0.9552446001570939 1851 | 0.9965138369157395 1852 | 0.9384233274009556 1853 | 0.8432208830955465 1854 | 0.9650019647300661 1855 | 1 1856 | 0.9173727476264228 1857 | 0.8158134305503734 1858 | 0.6524820681853531 1859 | 0.9758440829389672 1860 | 0.8713931412670036 1861 | 0.02827143676776534 1862 | 0.04618682202019265 1863 | 1.075566614249062e-13 1864 | 4.621550959483922e-14 1865 | 0 1866 | 9.999850229585171e-14 1867 | 0 1868 | 0.8271927052963892 1869 | 0.7929033172594985 1870 | 0.6498313730804539 1871 | 0.7536852727523008 1872 | 0.6955377223589333 1873 | 0.7395341472010422 1874 | 0.9704322858055838 1875 | 1.504973488227796e-13 1876 | 1.31225518373583e-13 1877 | 0.4027088951153222 1878 | 0.4924191209545416 1879 | 0.5587221475485573 1880 | 1.695621318042768e-14 1881 | 1.151325025838377e-13 1882 | 0.1349542727065692 1883 | 0.1633154529685958 1884 | 0.001177284198657245 1885 | 0.000868972071275548 1886 | 0 1887 | 0.003619697810391376 1888 | 0.2252488274982816 1889 | 7.593641885725697e-14 1890 | 5.266647611848227e-14 1891 | 8.077599025711559e-14 1892 | 0.2920047737593156 1893 | 3.740689423656505e-13 1894 | 2.402820107681245e-13 1895 | 0.8233611954021751 1896 | 6.327171480270065e-13 1897 | 8.388530250176962e-13 1898 | 4.264519961321134e-13 1899 | 3.353189234732319e-13 1900 | 2.695230987824025e-13 1901 | 2.772097325090183e-13 1902 | 0.847729025433548 1903 | 0.7100557785489704 1904 | 0.9871217508896362 1905 | 0.9814075821272256 1906 | 0.018914182372066 1907 | 7.313943327213572e-14 1908 | 0.594369900841991 1909 | 0.5737150643792519 1910 | 3.975590320760601e-25 1911 | 3.302256014367782e-13 1912 | 3.708912049006991e-13 1913 | 1.957292367360978e-13 1914 | 1.860965595615884e-13 1915 | 5.736947245338924e-14 1916 | 3.604118076240727e-14 1917 | 9.262471545085036e-14 1918 | 1.253234157062236e-13 1919 | -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth.json: -------------------------------------------------------------------------------- 1 | { 2 | "mesh_file": "./bird_mouth_data/bird_mouth.obj", 3 | "handle_file": "./bird_mouth_data/bird_mouth.tgf", 4 | "weight_file": "./bird_mouth_data/bird_mouth.dmat", 5 | "anim_file": "./bird_mouth_data/bird_mouth_anim.txt", 6 | "dt": 0.01, 7 | "YM": 175, 8 | "pr": 0.4, 9 | "with_dynamics": 1, 10 | "frame_num": 5000 11 | } -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/examples/bird/bird_mouth_data/bird_mouth.png -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth.tgf: -------------------------------------------------------------------------------- 1 | 1 238.01512786 234.528503962 0.0 2 | 2 383.199327966 463.596908574 0.0 3 | 3 447.725639124 24.8179926979 0.0 4 | 4 130.740135559 212.750873946 0.0 5 | # 6 | 1 2 1 0 0 0 7 | 1 3 1 0 0 0 8 | 1 4 1 0 0 0 9 | # 10 | -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth_anim.txt: -------------------------------------------------------------------------------- 1 | 140 3 2 | 238.01512786 234.528503962 0.0 238.01512786 234.528503962 0.0 238.01512786 234.528503962 0.0 3 | 238.01512786 234.528503962 0.0 238.01512786 234.528503962 0.0 238.01512786 234.528503962 0.0 4 | 238.290424581 234.379798355 -0.280653156437 238.290424581 234.379798355 0.280653156437 238.290424581 234.379798355 -0.140951366315 5 | 239.111678169 233.94402627 -1.08179034845 239.111678169 233.94402627 1.08179034845 239.111678169 233.94402627 -0.550539454311 6 | 240.471933759 233.236704816 -2.34217816008 240.471933759 233.236704816 2.34217816008 240.471933759 233.236704816 -1.20886524757 7 | 242.364236486 232.273351099 -4.00058317539 242.364236486 232.273351099 4.00058317539 242.364236486 232.273351099 -2.09602972967 8 | 244.781631485 231.069482225 -5.99577197842 244.781631485 231.069482225 5.99577197842 244.781631485 231.069482225 -3.19213388418 9 | 247.717163893 229.640615301 -8.26651115323 247.717163893 229.640615301 8.26651115323 247.717163893 229.640615301 -4.4772786947 10 | 251.163878844 228.002267435 -10.7515672839 251.163878844 228.002267435 10.7515672839 251.163878844 228.002267435 -5.93156514479 11 | 255.114821475 226.169955734 -13.3897069544 255.114821475 226.169955734 13.3897069544 255.114821475 226.169955734 -7.53509421804 12 | 259.56303692 224.159197303 -16.1196967488 259.56303692 224.159197303 16.1196967488 259.56303692 224.159197303 -9.26796689803 13 | 264.501570315 221.98550925 -18.8803032512 264.501570315 221.98550925 18.8803032512 264.501570315 221.98550925 -11.1102841683 14 | 269.923466796 219.664408683 -21.6102930456 269.923466796 219.664408683 21.6102930456 269.923466796 219.664408683 -13.0421470125 15 | 275.821771498 217.211412707 -24.2484327161 275.821771498 217.211412707 24.2484327161 275.821771498 217.211412707 -15.0436564142 16 | 282.189529556 214.642038429 -26.7334888468 282.189529556 214.642038429 26.7334888468 282.189529556 214.642038429 -17.0949133569 17 | 289.019786106 211.971802957 -29.0042280216 289.019786106 211.971802957 29.0042280216 289.019786106 211.971802957 -19.1760188243 18 | 296.305586283 209.216223397 -30.9994168246 296.305586283 209.216223397 30.9994168246 296.305586283 209.216223397 -21.2670737998 19 | 304.039975224 206.390816856 -32.6578218399 304.039975224 206.390816856 32.6578218399 304.039975224 206.390816856 -23.3481792672 20 | 312.215998062 203.511100442 -33.9182096516 312.215998062 203.511100442 33.9182096516 312.215998062 203.511100442 -25.3994362099 21 | 320.826699934 200.59259126 -34.7193468436 320.826699934 200.59259126 34.7193468436 320.826699934 200.59259126 -27.4009456116 22 | 329.865125976 197.650806418 -35.0 329.865125976 197.650806418 35.0 329.865125976 197.650806418 -29.3328084558 23 | 339.324321322 194.701263022 -34.74625 339.324321322 194.701263022 34.74625 339.324321322 194.701263022 -31.1751257261 24 | 349.197331108 191.75947818 -34.02 349.197331108 191.75947818 34.02 349.197331108 191.75947818 -32.9079984061 25 | 359.47720047 188.840968998 -32.87375 359.47720047 188.840968998 32.87375 359.47720047 188.840968998 -34.5115274793 26 | 370.156974542 185.961252583 -31.36 370.156974542 185.961252583 31.36 370.156974542 185.961252583 -35.9658139294 27 | 381.229698462 183.135846042 -29.53125 381.229698462 183.135846042 29.53125 381.229698462 183.135846042 -37.2509587399 28 | 392.688417363 180.380266483 -27.44 392.688417363 180.380266483 27.44 392.688417363 180.380266483 -38.3470628944 29 | 404.526176381 177.71003101 -25.13875 404.526176381 177.71003101 25.13875 404.526176381 177.71003101 -39.2342273765 30 | 416.736020653 175.140656733 -22.68 416.736020653 175.140656733 22.68 416.736020653 175.140656733 -39.8925531698 31 | 429.310995313 172.687660757 -20.11625 429.310995313 172.687660757 20.11625 429.310995313 172.687660757 -40.3021412578 32 | 442.244145496 170.366560189 -17.5 442.244145496 170.366560189 17.5 442.244145496 170.366560189 -40.4430926241 33 | 455.528516339 168.192872136 -14.88375 455.528516339 168.192872136 14.88375 455.528516339 168.192872136 -40.2317478779 34 | 469.157152977 166.182113706 -12.32 469.157152977 166.182113706 12.32 469.157152977 166.182113706 -39.6169267982 35 | 483.123100544 164.349802004 -9.86125 483.123100544 164.349802004 9.86125 483.123100544 164.349802004 -38.6274491229 36 | 497.419404178 162.711454138 -7.56 497.419404178 162.711454138 7.56 497.419404178 162.711454138 -37.2921345903 37 | 512.039109012 161.282587215 -5.46875 512.039109012 161.282587215 5.46875 512.039109012 161.282587215 -35.6398029384 38 | 526.975260183 160.078718341 -3.64 526.975260183 160.078718341 3.64 526.975260183 160.078718341 -33.6992739054 39 | 542.220902826 159.115364623 -2.12625 542.220902826 159.115364623 2.12625 542.220902826 159.115364623 -31.4993672294 40 | 557.769082077 158.408043169 -0.98 557.769082077 158.408043169 0.98 557.769082077 158.408043169 -29.0689026484 41 | 573.61284307 157.972271085 -0.25375 573.61284307 157.972271085 0.25375 573.61284307 157.972271085 -26.4366999007 42 | 589.745230942 157.823565477 0.0 589.745230942 157.823565477 0.0 589.745230942 157.823565477 -23.6315787242 43 | 606.159290828 158.723070005 -0.25375 606.159290828 158.723070005 0.25375 606.159290828 158.723070005 -20.6823588572 44 | 622.848067863 161.315456149 -0.98 622.848067863 161.315456149 0.98 622.848067863 161.315456149 -17.6178600378 45 | 639.804607183 165.441532749 -2.12625 639.804607183 165.441532749 2.12625 639.804607183 165.441532749 -14.466902004 46 | 657.021953923 170.942108647 -3.64 657.021953923 170.942108647 3.64 657.021953923 170.942108647 -11.2583044939 47 | 674.493153219 177.657992683 -5.46875 674.493153219 177.657992683 5.46875 674.493153219 177.657992683 -8.02088724581 48 | 692.211250206 185.429993698 -7.56 692.211250206 185.429993698 7.56 692.211250206 185.429993698 -4.78346999766 49 | 710.169290019 194.098920532 -9.86125 710.169290019 194.098920532 9.86125 710.169290019 194.098920532 -1.57487248763 50 | 728.360317795 203.505582027 -12.32 728.360317795 203.505582027 12.32 728.360317795 203.505582027 1.57608554617 51 | 746.777378668 213.490787023 -14.88375 746.777378668 213.490787023 14.88375 746.777378668 213.490787023 4.64058436563 52 | 765.413517774 223.895344361 -17.5 765.413517774 223.895344361 17.5 765.413517774 223.895344361 7.58980423263 53 | 784.261780249 234.560062881 -20.11625 784.261780249 234.560062881 20.11625 784.261780249 234.560062881 10.3949254091 54 | 803.315211227 245.325751424 -22.68 803.315211227 245.325751424 22.68 803.315211227 245.325751424 13.0271281568 55 | 822.566855845 256.033218832 -25.13875 822.566855845 256.033218832 25.13875 822.566855845 256.033218832 15.4575927378 56 | 842.009759238 266.523273944 -27.44 842.009759238 266.523273944 27.44 842.009759238 266.523273944 17.6574994138 57 | 861.636966541 276.636725602 -29.53125 861.636966541 276.636725602 29.53125 861.636966541 276.636725602 19.5980284468 58 | 881.44152289 286.214382646 -31.36 881.44152289 286.214382646 31.36 881.44152289 286.214382646 21.2503600987 59 | 901.41647342 295.097053917 -32.87375 901.41647342 295.097053917 32.87375 901.41647342 295.097053917 22.5856746313 60 | 921.554863267 303.125548255 -34.02 921.554863267 303.125548255 34.02 921.554863267 303.125548255 23.5751523065 61 | 941.849737566 310.140674502 -34.74625 941.849737566 310.140674502 34.74625 941.849737566 310.140674502 24.1899733863 62 | 962.294141452 315.983241498 -35.0 962.294141452 315.983241498 35.0 962.294141452 315.983241498 24.4013181325 63 | 982.881120062 320.935012245 -34.74625 982.881120062 320.935012245 34.74625 982.881120062 320.935012245 24.1899733863 64 | 1003.60371853 325.399945253 -34.02 1003.60371853 325.399945253 34.02 1003.60371853 325.399945253 23.5751523065 65 | 1024.45498199 329.402142624 -32.87375 1024.45498199 329.402142624 32.87375 1024.45498199 329.402142624 22.5856746313 66 | 1045.42795558 332.965706457 -31.36 1045.42795558 332.965706457 31.36 1045.42795558 332.965706457 21.2503600987 67 | 1066.51568444 336.114738856 -29.53125 1066.51568444 336.114738856 29.53125 1066.51568444 336.114738856 19.5980284468 68 | 1087.7112137 338.87334192 -27.44 1087.7112137 338.87334192 27.44 1087.7112137 338.87334192 17.6574994138 69 | 1109.00758849 341.265617752 -25.13875 1109.00758849 341.265617752 25.13875 1109.00758849 341.265617752 15.4575927378 70 | 1130.39785395 343.315668452 -22.68 1130.39785395 343.315668452 22.68 1130.39785395 343.315668452 13.0271281568 71 | 1151.87505522 345.047596122 -20.11625 1151.87505522 345.047596122 20.11625 1151.87505522 345.047596122 10.3949254091 72 | 1173.43223744 346.485502863 -17.5 1173.43223744 346.485502863 17.5 1173.43223744 346.485502863 7.58980423263 73 | 1195.06244573 347.653490777 -14.88375 1195.06244573 347.653490777 14.88375 1195.06244573 347.653490777 4.64058436563 74 | 1216.75872523 348.575661965 -12.32 1216.75872523 348.575661965 12.32 1216.75872523 348.575661965 1.57608554617 75 | 1238.51412108 349.276118527 -9.86125 1238.51412108 349.276118527 9.86125 1238.51412108 349.276118527 -1.57487248763 76 | 1260.32167842 349.778962566 -7.56 1260.32167842 349.778962566 7.56 1260.32167842 349.778962566 -4.78346999766 77 | 1282.17444237 350.108296183 -5.46875 1282.17444237 350.108296183 5.46875 1282.17444237 350.108296183 -8.02088724581 78 | 1304.06545809 350.288221479 -3.64 1304.06545809 350.288221479 3.64 1304.06545809 350.288221479 -11.2583044939 79 | 1325.98777069 350.342840555 -2.12625 1325.98777069 350.342840555 2.12625 1325.98777069 350.342840555 -14.466902004 80 | 1347.93442531 349.763292561 -0.98 1347.93442531 349.763292561 0.98 1347.93442531 349.763292561 -17.6178600378 81 | 1369.8984671 348.09027812 -0.25375 1369.8984671 348.09027812 0.25375 1369.8984671 348.09027812 -20.6823588572 82 | 1391.87294119 345.422241542 0.0 1391.87294119 345.422241542 0.0 1391.87294119 345.422241542 -23.6315787242 83 | 1413.85089271 341.857627135 -0.25375 1413.85089271 341.857627135 0.25375 1413.85089271 341.857627135 -26.4366999007 84 | 1435.82536679 337.494879209 -0.98 1435.82536679 337.494879209 0.98 1435.82536679 337.494879209 -29.0689026484 85 | 1457.78940858 332.432442075 -2.12625 1457.78940858 332.432442075 2.12625 1457.78940858 332.432442075 -31.4993672294 86 | 1479.73606321 326.768760041 -3.64 1479.73606321 326.768760041 3.64 1479.73606321 326.768760041 -33.6992739054 87 | 1501.65837581 320.602277418 -5.46875 1501.65837581 320.602277418 5.46875 1501.65837581 320.602277418 -35.6398029384 88 | 1523.54939152 314.031438515 -7.56 1523.54939152 314.031438515 7.56 1523.54939152 314.031438515 -37.2921345903 89 | 1545.40215547 307.154687642 -9.86125 1545.40215547 307.154687642 9.86125 1545.40215547 307.154687642 -38.6274491229 90 | 1567.20971281 300.070469108 -12.32 1567.20971281 300.070469108 12.32 1567.20971281 300.070469108 -39.6169267982 91 | 1588.96510866 292.877227223 -14.88375 1588.96510866 292.877227223 14.88375 1588.96510866 292.877227223 -40.2317478779 92 | 1610.66138817 285.673406297 -17.5 1610.66138817 285.673406297 17.5 1610.66138817 285.673406297 -40.4430926241 93 | 1632.29159646 278.557450639 -20.11625 1632.29159646 278.557450639 20.11625 1632.29159646 278.557450639 -40.2317478779 94 | 1653.84877867 271.627804559 -22.68 1653.84877867 271.627804559 22.68 1653.84877867 271.627804559 -39.6169267982 95 | 1675.32597994 264.982912367 -25.13875 1675.32597994 264.982912367 25.13875 1675.32597994 264.982912367 -38.6274491229 96 | 1696.7162454 258.721218372 -27.44 1696.7162454 258.721218372 27.44 1696.7162454 258.721218372 -37.2921345903 97 | 1718.0126202 252.941166884 -29.53125 1718.0126202 252.941166884 29.53125 1718.0126202 252.941166884 -35.6398029384 98 | 1739.20814945 247.741202213 -31.36 1739.20814945 247.741202213 31.36 1739.20814945 247.741202213 -33.6992739054 99 | 1760.29587831 242.723168019 -32.87375 1760.29587831 242.723168019 32.87375 1760.29587831 242.723168019 -31.4993672294 100 | 1781.2688519 237.555079406 -34.02 1781.2688519 237.555079406 34.02 1781.2688519 237.555079406 -29.0689026484 101 | 1802.12011536 232.43463784 -34.74625 1802.12011536 232.43463784 34.74625 1802.12011536 232.43463784 -26.4366999007 102 | 1822.84271383 227.559544793 -35.0 1822.84271383 227.559544793 35.0 1822.84271383 227.559544793 -23.6315787242 103 | 1843.42969244 223.127501733 -34.74625 1843.42969244 223.127501733 34.74625 1843.42969244 223.127501733 -20.6823588572 104 | 1863.87409633 219.336210128 -34.02 1863.87409633 219.336210128 34.02 1863.87409633 219.336210128 -17.6178600378 105 | 1884.16897063 216.383371449 -32.87375 1884.16897063 216.383371449 32.87375 1884.16897063 216.383371449 -14.466902004 106 | 1904.30736047 214.466687164 -31.36 1904.30736047 214.466687164 31.36 1904.30736047 214.466687164 -11.2583044939 107 | 1924.282311 213.783858743 -29.53125 1924.282311 213.783858743 29.53125 1924.282311 213.783858743 -8.02088724581 108 | 1944.08686735 214.702697684 -27.44 1944.08686735 214.702697684 27.44 1944.08686735 214.702697684 -4.78346999766 109 | 1963.71407465 217.321780024 -25.13875 1963.71407465 217.321780024 25.13875 1963.71407465 217.321780024 -1.57487248763 110 | 1983.15697805 221.434954033 -22.68 1983.15697805 221.434954033 22.68 1983.15697805 221.434954033 1.57608554617 111 | 2002.40862267 226.836067985 -20.11625 2002.40862267 226.836067985 20.11625 2002.40862267 226.836067985 4.64058436563 112 | 2021.46205364 233.31897015 -17.5 2021.46205364 233.31897015 17.5 2021.46205364 233.31897015 7.58980423263 113 | 2040.31031612 240.677508801 -14.88375 2040.31031612 240.677508801 14.88375 2040.31031612 240.677508801 10.3949254091 114 | 2058.94645522 248.70553221 -12.32 2058.94645522 248.70553221 12.32 2058.94645522 248.70553221 13.0271281568 115 | 2077.3635161 257.196888649 -9.86125 2077.3635161 257.196888649 9.86125 2077.3635161 257.196888649 15.4575927378 116 | 2095.55454387 265.945426389 -7.56 2095.55454387 265.945426389 7.56 2095.55454387 265.945426389 17.6574994138 117 | 2113.51258369 274.744993703 -5.46875 2113.51258369 274.744993703 5.46875 2113.51258369 274.744993703 19.5980284468 118 | 2131.23068067 283.389438864 -3.64 2131.23068067 283.389438864 3.64 2131.23068067 283.389438864 21.2503600987 119 | 2148.70187997 291.672610142 -2.12625 2148.70187997 291.672610142 2.12625 2148.70187997 291.672610142 22.5856746313 120 | 2165.91922671 299.388355809 -0.98 2165.91922671 299.388355809 0.98 2165.91922671 299.388355809 23.5751523065 121 | 2182.87576603 306.330524139 -0.25375 2182.87576603 306.330524139 0.25375 2182.87576603 306.330524139 24.1899733863 122 | 2199.56454306 312.292963402 0.0 2199.56454306 312.292963402 0.0 2199.56454306 312.292963402 24.4013181325 123 | 2215.97860295 317.766246207 -0.25375 2215.97860295 317.766246207 0.25375 2215.97860295 317.766246207 24.1899733863 124 | 2232.11099082 323.309065283 -0.98 2232.11099082 323.309065283 0.98 2232.11099082 323.309065283 23.5751523065 125 | 2247.95475182 328.817449084 -2.12625 2247.95475182 328.817449084 2.12625 2247.95475182 328.817449084 22.5856746313 126 | 2263.50293107 334.187426065 -3.64 2263.50293107 334.187426065 3.64 2263.50293107 334.187426065 21.2503600987 127 | 2278.74857371 339.31502468 -5.46875 2278.74857371 339.31502468 5.46875 2278.74857371 339.31502468 19.5980284468 128 | 2293.68472488 344.096273384 -7.56 2293.68472488 344.096273384 7.56 2293.68472488 344.096273384 17.6574994138 129 | 2308.30442971 348.42720063 -9.86125 2308.30442971 348.42720063 9.86125 2308.30442971 348.42720063 15.4575927378 130 | 2322.60073335 352.203834873 -12.32 2322.60073335 352.203834873 12.32 2322.60073335 352.203834873 13.0271281568 131 | 2336.56668092 355.322204568 -14.88375 2336.56668092 355.322204568 14.88375 2336.56668092 355.322204568 10.3949254091 132 | 2350.19531755 357.678338168 -17.5 2350.19531755 357.678338168 17.5 2350.19531755 357.678338168 7.58980423263 133 | 2363.4796884 359.168264128 -20.11625 2363.4796884 359.168264128 20.11625 2363.4796884 359.168264128 4.64058436563 134 | 2376.41283858 359.688010903 -22.68 2376.41283858 359.688010903 22.68 2376.41283858 359.688010903 1.57608554617 135 | 2388.98781324 359.03879688 -25.13875 2388.98781324 359.03879688 25.13875 2388.98781324 359.03879688 -1.57487248763 136 | 2401.19765751 357.180701574 -27.44 2401.19765751 357.180701574 27.44 2401.19765751 357.180701574 -4.78346999766 137 | 2413.03541653 354.248045126 -29.53125 2413.03541653 354.248045126 29.53125 2413.03541653 354.248045126 -8.02088724581 138 | 2424.49413543 350.37514768 -31.36 2424.49413543 350.37514768 31.36 2424.49413543 350.37514768 -11.2583044939 139 | 2435.56685935 345.696329379 -32.87375 2435.56685935 345.696329379 32.87375 2435.56685935 345.696329379 -14.466902004 140 | 2446.24663342 340.345910364 -34.02 2446.24663342 340.345910364 34.02 2446.24663342 340.345910364 -17.6178600378 141 | 2456.52650278 334.458210779 -34.74625 2456.52650278 334.458210779 34.74625 2456.52650278 334.458210779 -20.6823588572 142 | 2466.39951257 328.167550765 -35.0 2466.39951257 328.167550765 35.0 2466.39951257 328.167550765 -23.6315787242 143 | -------------------------------------------------------------------------------- /examples/bird/bird_mouth_data/bird_mouth_fixed_region.dmat: -------------------------------------------------------------------------------- 1 | 1 42 2 | 24 3 | 27 4 | 29 5 | 30 6 | 35 7 | 51 8 | 55 9 | 56 10 | 59 11 | 61 12 | 62 13 | 63 14 | 67 15 | 68 16 | 69 17 | 70 18 | 71 19 | 72 20 | 73 21 | 74 22 | 80 23 | 81 24 | 83 25 | 86 26 | 87 27 | 91 28 | 92 29 | 93 30 | 94 31 | 95 32 | 96 33 | 97 34 | 98 35 | 99 36 | 100 37 | 101 38 | 102 39 | 103 40 | 104 41 | 105 42 | 106 43 | 111 44 | -------------------------------------------------------------------------------- /examples/daisy/daisy.m: -------------------------------------------------------------------------------- 1 | clear; 2 | warning('off','all'); 3 | addpath('../../matlab-include/utils'); 4 | set_project_path(); 5 | 6 | % read json 7 | json = jsondecode(fileread('./daisy_data/daisy.json')); 8 | cellfun(@(x,y) assignin('base',x,y),fieldnames(json),struct2cell(json)); 9 | 10 | 11 | [V,F] = load_mesh(mesh_file); 12 | [C,~,PI,BE,CE,~] = readTGF(handle_file); 13 | V(:,3)=[]; 14 | C(:,3)=[]; 15 | [~,b] = farthest_points(V,5); 16 | H = kharmonic(V,F,b,linspace(0,1,numel(b))'); 17 | 18 | T_list = read_2d_pnt_anim(anim_file,C,PI); 19 | W = save_bbw_pnt(weight_file, V,F,C); 20 | 21 | I = eye(size(PI,2)); 22 | CM = lbs_matrix(C,I); 23 | VM = lbs_matrix(V,W); 24 | 25 | 26 | % normalize the mesh 27 | mesh_center = (max(V)+min(V))/2; 28 | V = V - mesh_center; 29 | mesh_scale = max(V(:)); 30 | V = V/mesh_scale; 31 | C = C - mesh_center; 32 | C = C/mesh_scale; 33 | 34 | vec = @(X) reshape(X',size(X,1)*size(X,2),1); 35 | 36 | M = massmatrix_xyz(V,F); 37 | A = lbs_matrix_xyz(V,W); 38 | 39 | % no external force use the default D matrix 40 | [phi,Em] = default_D_matrix(V,F); 41 | 42 | mask = M * phi; 43 | 44 | g = 0*vec(repmat([0 -9.8],size(V,1),1)); % didn't add any external gravity in this example 45 | Beq = zeros(size(A', 1),1); 46 | 47 | % Bartels 48 | [lambda, mu] = emu_to_lame(YM*ones(size(F,1),1), pr*ones(size(F,1),1)); 49 | dX = linear_tri2dmesh_dphi_dX(V,F); 50 | areas = triangle_area(V,F); 51 | 52 | energy_func = @(a,b,c,d,e) linear_tri2dmesh_arap_q(a,b,c,d,e,[0.5*lambda,mu]); 53 | gradient_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq(a,b,c,d,e,[0.5*lambda,mu]); 54 | hessian_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq2(a,b,c,d,e,[0.5*lambda,mu],'fixed'); 55 | 56 | % plot the wire 57 | sample_num = 30; 58 | [X0,Y0,tX0,tY0,nX0,nY0] = catmull_rom_handle(C(:,1),C(:,2),sample_num); % reference frame 59 | Wv = [X0 Y0]; 60 | [I] = cluster_pnts_to_closest(V,Wv); 61 | 62 | % Don't move 63 | U = vec(zeros(size(V))); 64 | Ud = vec(zeros(size(V))); 65 | Uc = vec(zeros(size(V))); 66 | 67 | 68 | clf; 69 | hold on; 70 | t = tsurf(F,V,'FaceColor',blue,'FaceAlpha',0.8,'EdgeAlpha',0.8); 71 | C_plot = scatter3( ... 72 | C(:,1),C(:,2),0*C(:,1), ... 73 | 'o','MarkerFaceColor',[1 1 1], 'MarkerEdgeColor','k',... 74 | 'LineWidth',2,'SizeData',50); 75 | L_plot = line('XData',X0,'YData',Y0,'LineWidth',1.5,'Color',[1 1 1]); 76 | hold off; 77 | axis equal; 78 | expand_axis(3); 79 | % axis(5*[-0.5 1.5 -0.3 0.3]); 80 | axis manual; 81 | drawnow; 82 | 83 | 84 | avg_edge_len = avgedge(V,F); % before loop 85 | 86 | Ti = zeros(1,size(T_list,1)); 87 | 88 | for ai = 1:size(T_list,1) 89 | 90 | % read a new frame 91 | TCol = T_list{ai,1}; 92 | 93 | CCol = CM*TCol; 94 | new_C = reshape(CCol, size(C)); 95 | new_C = new_C-mesh_center; 96 | new_C = new_C/mesh_scale; 97 | 98 | [Vr,X,Y] = wire_deform(V,I,new_C,sample_num,X0,Y0,tX0,tY0,nX0,nY0); 99 | Ud0 = Ud; 100 | U0 = U; 101 | Uc0 = Uc; 102 | Ur = vec(Vr)-vec(V); % rig displacement 103 | 104 | 105 | if with_dynamics 106 | 107 | % compute the jacobian 108 | h = 1e-8; 109 | J = zeros(size(V,1)*size(V,2), size(new_C,1)*size(new_C,2)); 110 | Vtmp = zeros(size(V)); 111 | % finite difference 112 | for i = 1:size(J,2) 113 | row = ceil(i/2); 114 | col = (i-row*2)+2; 115 | new_C(row,col) = new_C(row,col) + h; 116 | [Vtmp,~,~] = wire_deform(V,I,new_C,sample_num,X0,Y0,tX0,tY0,nX0,nY0); 117 | J(:,i) = (vec(Vtmp) - vec(Vr))/h; 118 | new_C(row,col) = new_C(row,col) - h; 119 | end 120 | Aeq = J' * mask; 121 | Beq = zeros(size(J',1),1); 122 | 123 | 124 | % instead of one direct solve: do newton here 125 | max_iter = 20; 126 | % Uc = vec(zeros(size(V))); % initial guess for Uc 127 | for i = 1 : max_iter 128 | 129 | % total energy = gravitational potential energy + kinetic energy + 130 | % elastic potential energy 131 | G = gradient_func(V,F,vec(V)+Ur+Uc,dX,areas); 132 | K = hessian_func(V,F,vec(V)+Ur+Uc,dX,areas); 133 | 134 | f = @(Ur,Uc) -(M*g)'*(vec(V)+Ur+Uc) + 0.5*(Ur+Uc-U0-dt*Ud0)'*M/(dt*dt)*(Ur+Uc-U0-dt*Ud0) + ... 135 | energy_func(V,F,vec(V)+Ur+Uc,dX,areas); 136 | 137 | 138 | tmp_H = M/(dt^2) + K; 139 | tmp_g = M/(dt^2) * (Ur+Uc) - M*(g+U0/dt^2+Ud0/dt) + G; 140 | 141 | % solve for the update 142 | tmp_H = 0.5 * (tmp_H + tmp_H'); 143 | dUc = speye(size(tmp_H,1),size(tmp_H,1)+size(Aeq,1)) * ([tmp_H Aeq';Aeq sparse(size(Aeq,1),size(Aeq,1))] \ [-tmp_g;Beq]); 144 | 145 | % check for newton convergence criterian 146 | if tmp_g' * dUc > -1e-6 147 | break; 148 | end 149 | 150 | % backtracking line search 151 | alpha = newton_line_search(f,tmp_g,dUc,Ur,Uc); 152 | Uc = Uc + alpha * dUc; 153 | 154 | end 155 | end 156 | 157 | U = Ur + Uc; 158 | Ud = (U-U0)/dt; 159 | 160 | t.Vertices = V+reshape(U,size(V,2),size(V,1))'; 161 | set(C_plot,'XData',new_C(:,1)); 162 | set(C_plot,'YData',new_C(:,2)); 163 | set(L_plot,'XData',X); 164 | set(L_plot,'YData',Y); 165 | title(sprintf('%d',ai),'Fontsize',20); 166 | drawnow; 167 | 168 | 169 | end 170 | 171 | 172 | -------------------------------------------------------------------------------- /examples/daisy/daisy_data/daisy.json: -------------------------------------------------------------------------------- 1 | { 2 | "mesh_file": "./daisy_data/daisy.obj", 3 | "handle_file": "./daisy_data/daisy.tgf", 4 | "weight_file": "./daisy_data/daisy.dmat", 5 | "anim_file": "./daisy_data/daisy_anim.txt", 6 | "dt": 0.01, 7 | "YM": 300, 8 | "pr": 0.4, 9 | "with_dynamics": 1 10 | } 11 | -------------------------------------------------------------------------------- /examples/daisy/daisy_data/daisy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/examples/daisy/daisy_data/daisy.png -------------------------------------------------------------------------------- /examples/daisy/daisy_data/daisy.tgf: -------------------------------------------------------------------------------- 1 | 1 373.794524538 64.3050619482 0.0 2 | 2 343.671644892 665.966043982 -8.28129211181e-31 3 | 3 336.14092498 1387.29878507 -2.61833624501e-15 4 | # 5 | # 6 | -------------------------------------------------------------------------------- /examples/daisy/daisy_data/daisy_anim.txt: -------------------------------------------------------------------------------- 1 | 200 3 2 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 -8.28129211181e-31 336.14092498 1387.29878507 -2.61833624501e-15 3 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 0.0 336.14092498 1387.29878507 0.0 4 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 0.16086511898 331.248112284 1385.20186534 0.586882238968 5 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 0.620061913159 317.281356042 1379.21611267 2.26216426657 6 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 1.3424925384 295.308179025 1369.7990368 4.89779904884 7 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 2.29305915055 266.396104003 1357.40814751 8.36573955183 8 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 3.43666390548 231.612653746 1342.50095454 12.5379387416 9 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 4.73820895905 192.025351023 1325.53496766 17.2863495841 10 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 6.16259646711 148.701718605 1306.96769662 22.4829250455 11 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 7.67472858552 102.709279262 1287.25665119 27.9996180918 12 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 9.23950747014 55.1155557638 1266.85934112 33.7083816891 13 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 10.8218352768 6.98807088065 1246.23327617 39.4811688033 14 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 12.3866141615 -40.6056526175 1225.8359661 45.1899324005 15 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 13.8987462799 -86.5980919605 1206.12492067 50.7066254468 16 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 15.3231337879 -129.921724378 1187.55764963 55.9032009082 17 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 16.6246788415 -169.509027101 1170.59166275 60.6516117508 18 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 17.7682835964 -204.292477359 1155.68446978 64.8238109405 19 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 18.7188502086 -233.204552381 1143.29358049 68.2917514435 20 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 19.4412808338 -255.177729398 1133.87650462 70.9273862258 21 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 19.900477628 -269.144485639 1127.89075195 72.6026682534 22 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 20.061342747 -274.037298335 1125.79383222 73.1895504923 23 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 19.9761380501 -271.062679497 1127.68974313 72.6589262513 24 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 19.7279031888 -262.443912092 1133.1159709 71.1402430786 25 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 19.3277070074 -248.63862979 1141.68025811 68.7432852999 26 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 18.7866183501 -230.104466257 1152.99034732 65.5778372411 27 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 18.1157060612 -207.29905516 1166.6539811 61.7536832279 28 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 17.3260389848 -180.680030168 1182.27890204 57.380607586 29 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 16.4286859651 -150.705024948 1199.47285269 52.5683946411 30 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 15.4347158465 -117.831673167 1217.84357562 47.426828719 31 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 14.3551974731 -82.5176084923 1236.99881342 42.0656941455 32 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 13.2011996892 -45.2204645922 1256.54630865 36.5947752462 33 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 11.983791339 -6.39787513373 1276.09380387 31.1238563469 34 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 10.7140412667 33.4925262155 1295.24904167 25.7627217733 35 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 9.40301831648 73.9931057881 1313.61976461 20.6211558512 36 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 8.06179133265 114.646229916 1330.81371526 15.8089429063 37 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 6.70142915942 154.994264933 1346.43863619 11.4358672644 38 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 5.333000641 194.579577171 1360.10226997 7.6117132512 39 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 3.96757462162 232.944532962 1371.41235918 4.44626519241 40 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 2.61621994551 269.631498638 1379.97664639 2.04930741379 41 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 1.2900054569 304.182840534 1385.40287416 0.53062424107 42 | 373.794524538 64.3050619482 0.0 343.671644892 665.966043982 0.0 336.14092498 1387.29878507 0.0 43 | 373.794524538 64.3050619482 0.0 344.40043788 665.966043982 -1.28108698385 372.664450061 1385.45422331 -0.643968206568 44 | 373.794524538 64.3050619482 0.0 346.486293674 665.966043982 -2.58800560952 412.151697941 1380.12693659 -2.48704962537 45 | 373.794524538 64.3050619482 0.0 349.778427518 665.966043982 -3.92087636709 454.079658715 1371.62652272 -5.39600945504 46 | 373.794524538 64.3050619482 0.0 354.126054656 665.966043982 -5.27981974663 497.925322476 1360.26257952 -9.23761289422 47 | 373.794524538 64.3050619482 0.0 359.37839033 665.966043982 -6.6649562382 543.165679319 1346.34470481 -13.8786251416 48 | 373.794524538 64.3050619482 0.0 365.384649786 665.966043982 -8.07640633188 589.277719338 1330.1824964 -19.1858113957 49 | 373.794524538 64.3050619482 0.0 371.994048267 665.966043982 -9.51429051775 635.738432628 1312.08555212 -25.0259368552 50 | 373.794524538 64.3050619482 0.0 379.055801016 665.966043982 -10.9787292859 682.024809282 1292.36346977 -31.2657667189 51 | 373.794524538 64.3050619482 0.0 386.419123278 665.966043982 -12.4698431263 727.613839395 1271.32584719 -37.7720661852 52 | 373.794524538 64.3050619482 0.0 393.933230296 665.966043982 -13.9877525291 771.982513062 1249.28228218 -44.411600453 53 | 373.794524538 64.3050619482 0.0 401.447337314 665.966043982 -15.5325779844 814.607820377 1226.54237256 -51.0511347207 54 | 373.794524538 64.3050619482 0.0 408.810659576 665.966043982 -17.1044399823 854.966751433 1203.41571616 -57.557434187 55 | 373.794524538 64.3050619482 0.0 415.872412325 665.966043982 -18.7034590127 892.536296326 1180.21191078 -63.7972640507 56 | 373.794524538 64.3050619482 0.0 422.481810806 665.966043982 -20.3297555658 926.793445149 1157.24055425 -69.6373895103 57 | 373.794524538 64.3050619482 0.0 428.488070262 665.966043982 -21.9834501317 957.215187997 1134.81124439 -74.9445757644 58 | 373.794524538 64.3050619482 0.0 433.740405936 665.966043982 -23.6646632004 983.278514964 1113.23357901 -79.5855880117 59 | 373.794524538 64.3050619482 0.0 438.088033074 665.966043982 -25.373515262 1004.46041615 1092.81715593 -83.4271914509 60 | 373.794524538 64.3050619482 0.0 441.380166918 665.966043982 -27.1101268065 1020.23788163 1073.87157296 -86.3361512806 61 | 373.794524538 64.3050619482 0.0 443.466022712 665.966043982 -28.8746183241 1030.08790152 1056.70642793 -88.1792326994 62 | 373.794524538 64.3050619482 0.0 444.1948157 665.966043982 -30.6671103048 1033.48746591 1041.63131866 -88.8232009059 63 | 373.794524538 64.3050619482 0.0 444.1948157 668.380027192 -32.789209636 1033.48746591 1028.33063571 -88.8232009059 64 | 373.794524538 64.3050619482 0.0 444.1948157 674.932267335 -35.4264732858 1033.48746591 1016.30240982 -88.8232009059 65 | 373.794524538 64.3050619482 0.0 444.1948157 684.588200176 -38.4049468651 1033.48746591 1005.57669901 -88.8232009059 66 | 373.794524538 64.3050619482 0.0 444.1948157 696.313261484 -41.5506759848 1033.48746591 996.183561338 -88.8232009059 67 | 373.794524538 64.3050619482 0.0 444.1948157 709.072887025 -44.689706256 1033.48746591 988.153054835 -88.8232009059 68 | 373.794524538 64.3050619482 0.0 444.1948157 721.832512565 -47.6480832897 1033.48746591 981.515237546 -88.8232009059 69 | 373.794524538 64.3050619482 0.0 444.1948157 733.557573873 -50.2518526968 1033.48746591 976.300167509 -88.8232009059 70 | 373.794524538 64.3050619482 0.0 444.1948157 743.213506715 -52.3270600882 1033.48746591 972.537902766 -88.8232009059 71 | 373.794524538 64.3050619482 0.0 444.1948157 749.765746857 -53.699751075 1033.48746591 970.258501357 -88.8232009059 72 | 373.794524538 64.3050619482 0.0 444.1948157 752.179730068 -54.1959712682 1033.48746591 969.492021323 -88.8232009059 73 | 373.794524538 64.3050619482 0.0 446.210421224 747.724768128 -52.9131940673 1033.48746591 972.774359352 -88.8232009059 74 | 373.794524538 64.3050619482 0.0 451.681350501 735.632728578 -49.4313702362 1033.48746591 981.683562573 -88.8232009059 75 | 373.794524538 64.3050619482 0.0 459.743772594 717.812880821 -44.3002614325 1033.48746591 994.812914688 -88.8232009059 76 | 373.794524538 64.3050619482 0.0 469.533856563 696.174494258 -38.0696293137 1033.48746591 1010.7556994 -88.8232009059 77 | 373.794524538 64.3050619482 0.0 480.187771472 672.626838292 -31.2892355374 1033.48746591 1028.10520041 -88.8232009059 78 | 373.794524538 64.3050619482 0.0 490.84168638 649.079182327 -24.5088417611 1033.48746591 1045.45470142 -88.8232009059 79 | 373.794524538 64.3050619482 0.0 500.63177035 627.440795764 -18.2782096424 1033.48746591 1061.39748613 -88.8232009059 80 | 373.794524538 64.3050619482 0.0 508.694192443 609.620948006 -13.1471008387 1033.48746591 1074.52683825 -88.8232009059 81 | 373.794524538 64.3050619482 0.0 514.16512172 597.528908457 -9.66527700758 1033.48746591 1083.43604147 -88.8232009059 82 | 373.794524538 64.3050619482 0.0 516.180727243 593.073946517 -8.38249980665 1033.48746591 1086.7183795 -88.8232009059 83 | 373.794524538 64.3050619482 0.0 516.180727243 598.014237254 -9.8770983486 1033.48746591 1084.02517906 -88.8232009059 84 | 373.794524538 64.3050619482 0.0 516.180727243 611.423597827 -13.9338658196 1033.48746591 1076.7150636 -88.8232009059 85 | 373.794524538 64.3050619482 0.0 516.180727243 631.184760775 -19.9122599874 1033.48746591 1065.94226186 -88.8232009059 86 | 373.794524538 64.3050619482 0.0 516.180727243 655.180458641 -27.1717386197 1033.48746591 1052.86100261 -88.8232009059 87 | 373.794524538 64.3050619482 0.0 516.180727243 681.293423966 -35.0717594843 1033.48746591 1038.6255146 -88.8232009059 88 | 373.794524538 64.3050619482 0.0 516.180727243 707.406389291 -42.9717803489 1033.48746591 1024.3900266 -88.8232009059 89 | 373.794524538 64.3050619482 0.0 516.180727243 731.402087157 -50.2312589812 1033.48746591 1011.30876735 -88.8232009059 90 | 373.794524538 64.3050619482 0.0 516.180727243 751.163250106 -56.209653149 1033.48746591 1000.53596561 -88.8232009059 91 | 373.794524538 64.3050619482 0.0 516.180727243 764.572610678 -60.26642062 1033.48746591 993.225850147 -88.8232009059 92 | 373.794524538 64.3050619482 0.0 516.180727243 769.512901415 -61.761019162 1033.48746591 990.532649713 -88.8232009059 93 | 373.794524538 64.3050619482 0.0 516.533616246 764.881115734 -60.3668101832 1033.48746591 994.404125337 -88.8232009059 94 | 373.794524538 64.3050619482 0.0 517.491457825 752.309126029 -56.5825286693 1033.48746591 1004.91241632 -88.8232009059 95 | 373.794524538 64.3050619482 0.0 518.903013836 733.781983305 -51.0056927541 1033.48746591 1020.39831881 -88.8232009059 96 | 373.794524538 64.3050619482 0.0 520.617046136 711.284738569 -44.2338205714 1033.48746591 1039.20262898 -88.8232009059 97 | 373.794524538 64.3050619482 0.0 522.48231658 686.802442827 -36.8644302549 1033.48746591 1059.66614299 -88.8232009059 98 | 373.794524538 64.3050619482 0.0 524.347587024 662.320147085 -29.4950399385 1033.48746591 1080.12965701 -88.8232009059 99 | 373.794524538 64.3050619482 0.0 526.061619323 639.822902349 -22.7231677558 1033.48746591 1098.93396718 -88.8232009059 100 | 373.794524538 64.3050619482 0.0 527.473175335 621.295759625 -17.1463318406 1033.48746591 1114.41986967 -88.8232009059 101 | 373.794524538 64.3050619482 0.0 528.431016914 608.723769919 -13.3620503267 1033.48746591 1124.92816065 -88.8232009059 102 | 373.794524538 64.3050619482 0.0 528.783905917 604.091984239 -11.9678413479 1033.48746591 1128.79963628 -88.8232009059 103 | 373.794524538 64.3050619482 0.0 528.783905917 606.996832333 -13.0011661702 1033.48746591 1124.17069803 -88.8232009059 104 | 373.794524538 64.3050619482 0.0 528.783905917 614.881420019 -15.8059049734 1033.48746591 1111.60643708 -88.8232009059 105 | 373.794524538 64.3050619482 0.0 528.783905917 626.500812398 -19.9392042625 1033.48746591 1093.09068409 -88.8232009059 106 | 373.794524538 64.3050619482 0.0 528.783905917 640.610074573 -24.958210542 1033.48746591 1070.60726976 -88.8232009059 107 | 373.794524538 64.3050619482 0.0 528.783905917 655.964271645 -30.4200703168 1033.48746591 1046.14002474 -88.8232009059 108 | 373.794524538 64.3050619482 0.0 528.783905917 671.318468718 -35.8819300916 1033.48746591 1021.67277973 -88.8232009059 109 | 373.794524538 64.3050619482 0.0 528.783905917 685.427730893 -40.9009363711 1033.48746591 999.189365393 -88.8232009059 110 | 373.794524538 64.3050619482 0.0 528.783905917 697.047123272 -45.0342356602 1033.48746591 980.67361241 -88.8232009059 111 | 373.794524538 64.3050619482 0.0 528.783905917 704.931710958 -47.8389744634 1033.48746591 968.109351457 -88.8232009059 112 | 373.794524538 64.3050619482 0.0 528.783905917 707.836559052 -48.8722992857 1033.48746591 963.480413211 -88.8232009059 113 | 373.794524538 64.3050619482 0.0 528.783905917 705.24200728 -47.8995796241 1033.48746591 965.416151023 -88.8232009059 114 | 373.794524538 64.3050619482 0.0 528.783905917 698.199652468 -45.2593405426 1033.48746591 970.670296512 -88.8232009059 115 | 373.794524538 64.3050619482 0.0 528.783905917 687.821445377 -41.3684618961 1033.48746591 978.41324776 -88.8232009059 116 | 373.794524538 64.3050619482 0.0 528.783905917 675.219336766 -36.6438235397 1033.48746591 987.815402846 -88.8232009059 117 | 373.794524538 64.3050619482 0.0 528.783905917 661.505277396 -31.5023053283 1033.48746591 998.047159852 -88.8232009059 118 | 373.794524538 64.3050619482 0.0 528.783905917 647.791218025 -26.3607871169 1033.48746591 1008.27891686 -88.8232009059 119 | 373.794524538 64.3050619482 0.0 528.783905917 635.189109415 -21.6361487605 1033.48746591 1017.68107194 -88.8232009059 120 | 373.794524538 64.3050619482 0.0 528.783905917 624.810902324 -17.745270114 1033.48746591 1025.42402319 -88.8232009059 121 | 373.794524538 64.3050619482 0.0 528.783905917 617.768547512 -15.1050310325 1033.48746591 1030.67816868 -88.8232009059 122 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 123 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 124 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 125 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 126 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 127 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 128 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 129 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 130 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 131 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 132 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 133 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 134 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 135 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 136 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 137 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 138 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 139 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 140 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 141 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 142 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 143 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 144 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 145 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 146 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 147 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 148 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 149 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 150 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 151 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 152 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 153 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 154 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 155 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 156 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 157 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 158 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 159 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 160 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 161 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 162 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 163 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 164 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 165 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 166 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 167 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 168 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 169 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 170 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 171 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 172 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 173 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 174 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 175 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 176 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 177 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 178 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 179 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 180 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 181 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 182 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 183 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 184 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 185 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 186 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 187 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 188 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 189 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 190 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 191 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 192 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 193 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 194 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 195 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 196 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 197 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 198 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 199 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 200 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 201 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 202 | 373.794524538 64.3050619482 0.0 528.783905917 615.173995739 -14.1323113708 1033.48746591 1032.61390649 -88.8232009059 203 | -------------------------------------------------------------------------------- /examples/hedgehog/hedgehog.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | warning('off','all'); 3 | addpath('../../matlab-include/utils'); 4 | set_project_path(); 5 | 6 | % read json 7 | json = jsondecode(fileread('./hedgehog_data/hedgehog.json')); 8 | cellfun(@(x,y) assignin('base',x,y),fieldnames(json),struct2cell(json)); 9 | 10 | 11 | [V,F] = load_mesh(mesh_file); 12 | V = V(:,1:2); 13 | BE = []; 14 | CE = []; 15 | PE = []; 16 | I = readDMAT(constraint_file); 17 | C = V(I,:); 18 | P = 1:size(C,1); % default value for point handle 19 | 20 | 21 | % normalize the mesh 22 | Vcenter = (min(V)+max(V))*0.5; 23 | V = V-Vcenter; 24 | Vbound = max(V(:)); 25 | V = V/Vbound; 26 | C = C-Vcenter; 27 | C = C/Vbound; 28 | [~,b] = farthest_points(V,5); 29 | H = kharmonic(V,F,b,linspace(0,1,numel(b))'); 30 | 31 | % % Compute boundary conditions 32 | [b,bc] = boundary_conditions(V,F,C,P,BE,CE); 33 | % Compute weights 34 | W = biharmonic_bounded(V,F,b,bc,'OptType','quad'); 35 | % Normalize weights 36 | W = W./repmat(sum(W,2),1,size(W,2)); 37 | 38 | 39 | vec = @(X) reshape(X',size(X,1)*size(X,2),1); 40 | M = massmatrix_xyz(V,F); 41 | 42 | A = lbs_matrix_xyz(V,W); 43 | 44 | % no external force use the default D matrix 45 | [phi,Em] = default_D_matrix(V,F); 46 | 47 | 48 | clf; 49 | hold on; 50 | t = tsurf(F,V,'FaceColor',blue,'FaceAlpha',0.8,'EdgeAlpha',0.8); 51 | % visualize the handles 52 | C_plot = scatter3( ... 53 | C(:,1),C(:,2),0*C(:,1), ... 54 | 'o','MarkerFaceColor',[1 1 1], 'MarkerEdgeColor','k',... 55 | 'LineWidth',2,'SizeData',50); 56 | axis equal; 57 | expand_axis(3); 58 | axis manual; 59 | drawnow; 60 | 61 | mask = M * phi; 62 | Aeq = A'*mask; 63 | Beq = zeros(size(A', 1),1); 64 | 65 | % Bartels 66 | [lambda, mu] = emu_to_lame(YM*ones(size(F,1),1), pr*ones(size(F,1),1)); 67 | dX = linear_tri2dmesh_dphi_dX(V,F); 68 | areas = triangle_area(V,F); 69 | 70 | energy_func = @(a,b,c,d,e) linear_tri2dmesh_arap_q(a,b,c,d,e,[0.5*lambda,mu]); 71 | gradient_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq(a,b,c,d,e,[0.5*lambda,mu]); 72 | hessian_func = @(a,b,c,d,e) linear_tri2dmesh_arap_dq2(a,b,c,d,e,[0.5*lambda,mu],'fixed'); 73 | 74 | 75 | % Don't move 76 | U = vec(zeros(size(V))); 77 | Ud = vec(zeros(size(V))); 78 | Uc = vec(zeros(size(V))); 79 | 80 | g = 0 * vec(repmat([9.8 0],size(V,1),1)); % no gravity 81 | 82 | user_T = readDMAT(anim_file); 83 | 84 | frame_num = size(user_T, 1); 85 | T = zeros(1,frame_num); 86 | 87 | % while loop for animation 88 | for iter = 1:frame_num 89 | 90 | Ud0 = Ud; 91 | U0 = U; 92 | 93 | Z = user_T(iter,:)'; 94 | new_Vr = reshape(A*Z,size(V,2),size(V,1))'; 95 | new_C = new_Vr(I,:); 96 | 97 | Ur = A*Z-vec(V); % rig displacement 98 | 99 | if with_dynamics 100 | 101 | % instead of one direct solve: do newton here 102 | max_iter = 20; 103 | for i = 1 : max_iter 104 | 105 | % total energy = gravitational potential energy + kinetic energy + 106 | % elastic potential energy 107 | G = gradient_func(V,F,vec(V)+Ur+Uc,dX,areas); 108 | K = hessian_func(V,F,vec(V)+Ur+Uc,dX,areas); 109 | 110 | f = @(Ur,Uc) -(M*g)'*(vec(V)+Ur+Uc) + 0.5*(Ur+Uc-U0-dt*Ud0)'*M/(dt*dt)*(Ur+Uc-U0-dt*Ud0) + ... 111 | energy_func(V,F,vec(V)+Ur+Uc,dX,areas); 112 | 113 | tmp_H = M/(dt^2) + K; 114 | tmp_g = M/(dt^2) * (Ur+Uc) - M*(g+U0/dt^2+Ud0/dt) + G; 115 | 116 | % solve for the update 117 | tmp_H = 0.5 * (tmp_H + tmp_H'); 118 | dUc = speye(size(tmp_H,1),size(tmp_H,1)+size(Aeq,1)) * ([tmp_H Aeq';Aeq sparse(size(Aeq,1),size(Aeq,1))] \ [-tmp_g;Beq]); 119 | 120 | 121 | % check for newton convergence criterian 122 | if tmp_g'*dUc > -1e-6 123 | break; 124 | end 125 | 126 | % backtracking line search 127 | alpha = newton_line_search(f,tmp_g,dUc,Ur,Uc); 128 | Uc = Uc + alpha * dUc; 129 | 130 | end 131 | 132 | end 133 | 134 | U = Ur + with_dynamics * Uc; 135 | Ud = (U-U0)/dt; 136 | 137 | t.Vertices = V+reshape(U,size(V,2),size(V,1))'; 138 | 139 | set(C_plot,'XData',new_C(:,1)); 140 | set(C_plot,'YData',new_C(:,2)); 141 | 142 | title(sprintf('%d',iter),'Fontsize',20); 143 | drawnow; 144 | 145 | % %%%%%%%%%%%%%%% save file %%%%%%%%%%%%%%% 146 | % U_output = V + reshape(U,size(V,2),size(V,1))'; 147 | % file_name = "./output/"; 148 | % 149 | % saveOBJ(U_output,F,file_name,iter); 150 | % %%%%%%%%%%%%%%% save file %%%%%%%%%%%%%%% 151 | 152 | end 153 | 154 | 155 | -------------------------------------------------------------------------------- /examples/hedgehog/hedgehog_data/hedgehog.json: -------------------------------------------------------------------------------- 1 | { 2 | "mesh_file": "./hedgehog_data/hedgehog.obj", 3 | "constraint_file": "./hedgehog_data/hedgehog_C_idx.dmat", 4 | "anim_file": "./hedgehog_data/hedgehog_T.dmat", 5 | "dt": 0.01, 6 | "YM": 800, 7 | "pr": 0.4, 8 | "with_dynamics": 1, 9 | "frame_num": 5000 10 | } 11 | -------------------------------------------------------------------------------- /examples/hedgehog/hedgehog_data/hedgehog.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/examples/hedgehog/hedgehog_data/hedgehog.png -------------------------------------------------------------------------------- /examples/hedgehog/hedgehog_data/hedgehog_C_idx.dmat: -------------------------------------------------------------------------------- 1 | 1 4 2 | 1242 3 | 1093 4 | 1313 5 | 1057 6 | -------------------------------------------------------------------------------- /examples/walrus/walrus.m: -------------------------------------------------------------------------------- 1 | clear all; 2 | warning('off','all'); 3 | addpath('../../matlab-include/utils'); 4 | set_project_path(); 5 | 6 | % read json 7 | json = jsondecode(fileread('./walrus_data/walrus.json')); 8 | cellfun(@(x,y) assignin('base',x,y),fieldnames(json),struct2cell(json)); 9 | 10 | [V,F] = load_mesh(mesh_file); 11 | V = V(:,1:2); 12 | [C,E] = readTGF(skeleton_file); 13 | C = C(:,1:2); 14 | 15 | 16 | % normalize vertices positions to be [-1 1 -1 1] 17 | Vcenter = (min(V)+max(V))*0.5; 18 | V = V-Vcenter; Vbound = max(V(:)); V = V/Vbound; 19 | C = C-Vcenter; C = C/Vbound; 20 | 21 | CE = E; % CE and E are the same in this case 22 | P = 1:size(C,1); 23 | BE = []; 24 | 25 | % compute Harmonic Coordinates W 26 | [TV,TF] = triangle([V;C],size(V,1) + CE,[],'Flags','-q31a0.01'); 27 | [b,bc] = boundary_conditions(TV,TF,C,P,[],CE); 28 | TW = kharmonic(TV,TF,b,bc,1); 29 | W = TW(1:size(V,1),:); 30 | 31 | vec = @(X) reshape(X',size(X,1)*size(X,2),1); 32 | M = massmatrix_xyz(V,F); 33 | 34 | % harmonic coordinates 35 | A = zeros(size(W,1)*2,size(W,2)*2); 36 | for i = 1:size(W,1) 37 | A(2*(i-1)+1:2*(i-1)+2,:) = repdiag(W(i,:),2); 38 | end 39 | 40 | % no external force use the default D matrix 41 | [phi,Em] = default_D_matrix(V,F); 42 | 43 | % viewr 44 | clf; 45 | hold on; 46 | t = tsurf(F,V,'FaceColor',blue,'FaceAlpha',0.8,'EdgeAlpha',0.8); 47 | C_plot = scatter3( ... 48 | C(:,1),C(:,2),0*C(:,1), ... 49 | 'o','MarkerFaceColor',[255 165 0]/255, 'MarkerEdgeColor',[255 165 0]/255,... 50 | 'LineWidth',1,'SizeData',50); 51 | % draw the cage 52 | L_plot = line('XData',C([CE(:,1);1],1),'YData',C([CE(:,1);1],2),'LineWidth',2,'Color',[255 165 0]/255); 53 | hold off; 54 | axis equal; 55 | expand_axis(1.5); 56 | axis manual; 57 | drawnow; 58 | 59 | 60 | mask = M * phi; 61 | Aeq = A' * mask; 62 | Beq = zeros(size(A', 1),1); 63 | 64 | % Bartels 65 | [lambda, mu] = emu_to_lame(YM*ones(size(F,1),1), pr*ones(size(F,1),1)); 66 | dX = linear_tri2dmesh_dphi_dX(V,F); 67 | areas = triangle_area(V,F); 68 | energy_func = @(a,b, c, d, e) linear_tri2dmesh_neohookean_q(a,b,c,d,e,[0.5*mu, 0.5*lambda]); 69 | gradient_func = @(a,b, c, d, e) linear_tri2dmesh_neohookean_dq(a,b,c,d,e,[0.5*mu, 0.5*lambda]); 70 | hessian_func = @(a,b, c, d, e) linear_tri2dmesh_neohookean_dq2(a,b,c,d,e,[0.5*mu, 0.5*lambda], 'fixed'); 71 | 72 | 73 | % Don't move 74 | U = vec(zeros(size(V))); 75 | Ud = vec(zeros(size(V))); 76 | Uc = vec(zeros(size(V))); 77 | 78 | g = 0 * vec(repmat([9.8 0],size(V,1),1)); % no gravity 79 | 80 | user_C = readDMAT(anim_file); 81 | 82 | frame_num = size(user_C,1); 83 | T = zeros(1,frame_num); 84 | 85 | % while loop for animation 86 | for iter = 1:frame_num 87 | 88 | Ud0 = Ud; 89 | U0 = U; 90 | 91 | new_C = user_C(iter,:)'; 92 | 93 | Ur = A * new_C - vec(V); % rig displacement 94 | 95 | if with_dynamics 96 | 97 | % instead of one direct solve: do newton here 98 | max_iter = 20; 99 | % Uc = vec(zeros(size(V))); % initial guess for Uc 100 | for i = 1 : max_iter 101 | 102 | % total energy = gravitational potential energy + kinetic energy + 103 | % elastic potential energy 104 | G = gradient_func(V,F,vec(V)+Ur+Uc,dX,areas); 105 | K = hessian_func(V,F,vec(V)+Ur+Uc,dX,areas); 106 | 107 | f = @(Ur,Uc) -(M*g)'*(vec(V)+Ur+Uc) + 0.5*(Ur+Uc-U0-dt*Ud0)'*M/(dt*dt)*(Ur+Uc-U0-dt*Ud0) + ... 108 | energy_func(V,F,vec(V)+Ur+Uc,dX,areas); 109 | 110 | tmp_H = M/(dt^2) + K; 111 | tmp_g = M/(dt^2) * (Ur+Uc) - M*(g+U0/dt^2+Ud0/dt) + G; 112 | 113 | 114 | tmp_H = 0.5 * (tmp_H + tmp_H'); 115 | dUc = speye(size(tmp_H,1),size(tmp_H,1)+size(Aeq,1)) * ([tmp_H Aeq';Aeq sparse(size(Aeq,1),size(Aeq,1))] \ [-tmp_g;Beq]); 116 | 117 | if tmp_g' * dUc > -1e-6 118 | break; 119 | end 120 | 121 | % backtracking line search 122 | alpha = newton_line_search(f,tmp_g,dUc,Ur,Uc); 123 | Uc = Uc + alpha * dUc; 124 | 125 | end 126 | end 127 | 128 | U = Ur + with_dynamics * Uc; 129 | Ud = (U-U0)/dt; 130 | 131 | % update the visualization 132 | set(t,'Vertices',V+reshape(U,size(V,2),size(V,1))'); 133 | new_C = reshape(new_C,size(new_C,1)/2,2); 134 | set(C_plot,'XData',new_C(:,1)); 135 | set(C_plot,'YData',new_C(:,2)); 136 | set(L_plot,'XData',new_C([CE(:,1);1],1)); 137 | set(L_plot,'YData',new_C([CE(:,1);1],2)); 138 | 139 | title(sprintf('%d',iter),'Fontsize',20); 140 | drawnow; 141 | 142 | end 143 | 144 | -------------------------------------------------------------------------------- /examples/walrus/walrus_data/walrus.json: -------------------------------------------------------------------------------- 1 | { 2 | "mesh_file": "./walrus_data/walrus.obj", 3 | "skeleton_file": "./walrus_data/walrus_cage.tgf", 4 | "anim_file": "./walrus_data/walrus_user_C.dmat", 5 | "dt": 0.005, 6 | "YM": 800, 7 | "pr": 0.45, 8 | "with_dynamics": 1 9 | } 10 | -------------------------------------------------------------------------------- /examples/walrus/walrus_data/walrus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/examples/walrus/walrus_data/walrus.png -------------------------------------------------------------------------------- /examples/walrus/walrus_data/walrus_cage.tgf: -------------------------------------------------------------------------------- 1 | 1 459.55 1694.14 0 2 | 2 -70.0554 1181.28 -0 3 | 3 -46.5648 472.176 -0 4 | 4 -26.8675 102.853 -0 5 | 5 539.428 48.6853 0 6 | 6 1302.7 -158.136 0 7 | 7 2209.88 172.764 0 8 | 8 2004.71 908.697 0 9 | 9 1138.91 1184.67 0 10 | # 11 | 1 2 12 | 2 3 13 | 3 4 14 | 4 5 15 | 5 6 16 | 6 7 17 | 7 8 18 | 8 9 19 | 9 1 20 | -------------------------------------------------------------------------------- /matlab-include/mex/compileAllMex.m: -------------------------------------------------------------------------------- 1 | eigenFolder = '../../libigl/external/eigen'; 2 | iglFolder = '../../libigl/include'; 3 | 4 | mex(['-I',eigenFolder],'energy_hessian_mex.cpp'); 5 | mex(['-I',eigenFolder],'precompute_mex.cpp'); 6 | mex(['-I',eigenFolder],'energy_value_mex.cpp'); 7 | mex(['-I',eigenFolder],['-I',iglFolder],'read_3d_bone_anim.cpp'); 8 | mex(['-I',eigenFolder],['-I',iglFolder],'read_3d_pnt_anim.cpp'); 9 | mex(['-I',eigenFolder],['-I',iglFolder],'read_blendshape_anim.cpp'); 10 | -------------------------------------------------------------------------------- /matlab-include/mex/energy_hessian_mex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace Eigen; 9 | using namespace std; 10 | 11 | 12 | double amips_param; 13 | double c1_param; 14 | double c2_param; 15 | double d1_param; 16 | 17 | 18 | Vector2d energy_derivative(int type, Vector2d S) 19 | { 20 | 21 | Vector2d es; 22 | double J; 23 | double l1; 24 | double l2; 25 | 26 | switch(type) 27 | { 28 | case 0: //arap 29 | es[0] = 2 * (S[0] - 1); 30 | es[1] = 2 * (S[1] - 1); 31 | break; 32 | 33 | case 1: // mips 34 | es[0] = 1.0 / S[1] - S[1] / (S[0] * S[0]); 35 | es[1] = 1.0 / S[0] - S[0] / (S[1] * S[1]); 36 | break; 37 | 38 | case 2: // iso 39 | es[0] = 2 * S[0] - 2.0 / (S[0] * S[0] * S[0]); 40 | es[1] = 2 * S[1] - 2.0 / (S[1] * S[1] * S[1]); 41 | break; 42 | 43 | case 3: // amips 44 | es[0] = amips_param * exp(amips_param * (S[0] / S[1] + S[1] / S[0])) * (1.0 / S[1] - S[1] / (S[0] * S[0])); 45 | es[1] = amips_param * exp(amips_param * (S[0] / S[1] + S[1] / S[0])) * (1.0 / S[0] - S[0] / (S[1] * S[1])); 46 | break; 47 | 48 | case 4: // conf 49 | es[0] = 2 * S[0] / (S[1] * S[1]); 50 | es[1] = -2 * S[0] * S[0] / (S[1] * S[1] * S[1]); 51 | break; 52 | 53 | case 5: // gmr 54 | es[0] = c1_param * (1.0 / S[1] - S[1] / (S[0] * S[0])) - d1_param *2.*S[1]*(1.0 - S[0]*S[1]); 55 | es[1] = c1_param * (1.0 / S[0] - S[0] / (S[1] * S[1])) - d1_param *2.*S[0]*(1.0 - S[0]*S[1]); 56 | 57 | break; 58 | 59 | case 6: // olg 60 | 61 | if(S[0] > 1.0 / S[1]) 62 | { 63 | es[0] = 1; 64 | es[1] = 0; 65 | }else{ 66 | es[0] = 0; 67 | es[1] = -1.0 / (S[1] * S[1]); 68 | } 69 | 70 | break; 71 | } 72 | 73 | return es; 74 | 75 | } 76 | 77 | 78 | double energy_hessian(double s1, double s2, double s1j, double s1k, double s2j, double s2k, double s1jk, double s2jk, int type) 79 | { 80 | 81 | double hessian = 0; 82 | double v1, v2; 83 | 84 | switch(type) 85 | { 86 | case 0: //arap 87 | v1 = 2 * ((s1 - 1) * s1jk + (s2 - 1) * s2jk); 88 | v2 = 2 * (s1j * s1k + s2j * s2k); 89 | hessian = v1 + v2; 90 | break; 91 | 92 | case 1: // mips 93 | 94 | v1 = - s2k / pow(s2, 2) - s2k /pow(s1, 2) + 2 * s2 * s1k / pow(s1, 3); 95 | v2 = - s1k / pow(s1, 2) - s1k /pow(s2, 2) + 2 * s1 * s2k / pow(s2, 3); 96 | 97 | hessian = v1 * s1j + v2 * s2j; 98 | 99 | v1 = 1.0 / s2 - s2 / pow(s1, 2); 100 | v2 = 1.0 / s1 - s1 / pow(s2, 2); 101 | 102 | hessian += v1 * s1jk + v2 * s2jk; 103 | 104 | break; 105 | 106 | case 2: // iso 107 | 108 | v1 = 2 * s1k * s1j + 2 * s1 * s1jk; 109 | v2 = 2 * s2k * s2j + 2 * s2 * s2jk; 110 | 111 | v1 += 6 * s1k * s1j / pow(s1, 4) - 2 * s1jk / pow(s1, 3); 112 | v2 += 6 * s2k * s2j / pow(s2, 4) - 2 * s2jk / pow(s2, 3); 113 | 114 | hessian = v1 + v2; 115 | 116 | break; 117 | 118 | case 3: // amips 119 | 120 | break; 121 | 122 | case 4: // conf 123 | v1 = (2 / (s1 * s1) * s1k - 4 * s1 / (s2 * s2 * s2) * s2k) * s1j + 2 * s1 / (s2 * s2) * s1jk; 124 | v2 = (6 * s1 * s1 / (s2 * s2 * s2 * s2) * s2k - 4 * s1 / (s2 * s2 * s2) * s1k) * s2j - 2 * s1 * s1 / (s2 * s2 * s2) * s2jk; 125 | 126 | hessian = v1 + v2; 127 | break; 128 | 129 | case 5: 130 | 131 | double e1 = c1_param * (1 / s2 - s2 / (s1 * s1)) + 2 * d1_param * s2 * (s1 * s2 - 1); 132 | double e2 = c1_param * (1 / s1 - s1 / (s2 * s2)) + 2 * d1_param * s1 * (s1 * s2 - 1); 133 | double e11 = 2 * c1_param * s2 / (s1 * s1 * s1) + 2 * d1_param * s2 * s2; 134 | double e22 = 2 * c1_param * s1 / (s2 * s2 * s2) + 2 * d1_param * s1 * s1; 135 | double e12 = c1_param * (-1 / (s1 * s1) - 1 / (s2 * s2)) + 2 * d1_param * (2 * s1 * s2 - 1); 136 | 137 | hessian = (e11 * s1k + e12 * s2k) * s1j + e1 * s1jk + (e12 * s1k + e22 * s2k) * s2j + e2 * s2jk; 138 | 139 | break; 140 | } 141 | 142 | return hessian; 143 | 144 | } 145 | 146 | 147 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 148 | { 149 | 150 | mxArray *row_mex, *col_mex, *val_mex, *grad_mex, *J_value_mex, *JT_value_mex, *wu_mex, *bu_mex; 151 | 152 | double *tri_num, *X_g_inv, *tri_areas, *obj_tri, *q_target, *type, *amips_s, *F_dot, *ver_num, *c1_g, *c2_g, *d1_g, *clamp, *J_index, *JT_index, *JTJ_info, *x2u; 153 | double *row, *col, *val, *grad, *J_value, *JT_value, *wu, *bu; 154 | 155 | 156 | // input list 157 | tri_num = mxGetPr(prhs[0]); 158 | X_g_inv = mxGetPr(prhs[1]); 159 | tri_areas = mxGetPr(prhs[2]); 160 | obj_tri = mxGetPr(prhs[3]); 161 | q_target = mxGetPr(prhs[4]); 162 | type = mxGetPr(prhs[5]); 163 | amips_s = mxGetPr(prhs[6]); 164 | F_dot = mxGetPr(prhs[7]); 165 | ver_num = mxGetPr(prhs[8]); 166 | c1_g = mxGetPr(prhs[9]); 167 | c2_g = mxGetPr(prhs[10]); 168 | d1_g = mxGetPr(prhs[11]); 169 | clamp = mxGetPr(prhs[12]); 170 | J_index = mxGetPr(prhs[13]); 171 | JT_index = mxGetPr(prhs[14]); 172 | JTJ_info = mxGetPr(prhs[15]); 173 | x2u = mxGetPr(prhs[16]); 174 | 175 | 176 | int tri_n = tri_num[0]; 177 | int ver_n = ver_num[0]; 178 | int energy_type = type[0]; 179 | double proj_threshold = clamp[0]; 180 | amips_param = amips_s[0]; 181 | c1_param = c1_g[0]; 182 | c2_param = c2_g[0]; 183 | d1_param = d1_g[0]; 184 | int J_rn = JTJ_info[0]; 185 | int J_cn = JTJ_info[1]; 186 | int JT_rn = JTJ_info[2]; 187 | int JT_cn = JTJ_info[3]; 188 | 189 | 190 | // output list 191 | grad_mex = plhs[0] = mxCreateDoubleMatrix(2 * ver_n, 1, mxREAL); 192 | J_value_mex = plhs[1] = mxCreateDoubleMatrix(J_rn * J_cn, 1, mxREAL); 193 | JT_value_mex = plhs[2] = mxCreateDoubleMatrix(JT_rn * JT_cn, 1, mxREAL); 194 | wu_mex = plhs[3] = mxCreateDoubleMatrix(tri_n, 1, mxREAL); 195 | bu_mex = plhs[4] = mxCreateDoubleMatrix(tri_n, 1, mxREAL); 196 | row_mex = plhs[5] = mxCreateDoubleMatrix(36 * tri_n, 1, mxREAL); 197 | col_mex = plhs[6] = mxCreateDoubleMatrix(36 * tri_n, 1, mxREAL); 198 | val_mex = plhs[7] = mxCreateDoubleMatrix(36 * tri_n, 1, mxREAL); 199 | 200 | 201 | grad = mxGetPr(grad_mex); 202 | J_value = mxGetPr(J_value_mex); 203 | JT_value = mxGetPr(JT_value_mex); 204 | wu = mxGetPr(wu_mex); 205 | bu = mxGetPr(bu_mex); 206 | row = mxGetPr(row_mex); 207 | col = mxGetPr(col_mex); 208 | val = mxGetPr(val_mex); 209 | 210 | memset(J_value, 0, J_rn * J_cn * sizeof(double)); 211 | memset(JT_value, 0, JT_rn * JT_cn * sizeof(double)); 212 | memset(grad, 0, 2 * ver_n * sizeof(double)); 213 | 214 | vector* offset = new vector; 215 | 216 | offset->resize(2 * ver_n, 0); 217 | 218 | int tri[3]; 219 | double tri_area; 220 | int index[6]; 221 | 222 | Vector2d es; 223 | Vector2d cs; 224 | 225 | double es1, es2; 226 | double d1, d2; 227 | double dphi; 228 | 229 | Matrix2d B, X_f, A, F_d, T_ddot, T; 230 | Vector2d S, u0, u1, v0, v1, temp_w; 231 | Matrix2d U, V; 232 | MatrixXd ELS(6, 6); 233 | VectorXd ELS_S; 234 | MatrixXd ELS_X; 235 | DiagonalMatrix ELS_D; 236 | 237 | Matrix2d T_dot[6]; 238 | Matrix2d w_U_dot[6]; 239 | Matrix2d w_V_dot[6]; 240 | 241 | Matrix2d temp_A, inv_A; 242 | 243 | Matrix2d II; 244 | II(0, 0) = 1; 245 | II(1, 1) = 1; 246 | II(0, 1) = 0; 247 | II(1, 0) = 0; 248 | 249 | double tao = 0.01; 250 | 251 | double value; 252 | 253 | for(int i = 0; i < tri_n; i++) 254 | { 255 | //mexPrintf("%d %d %d\n", (int)obj_tri[i], (int)obj_tri[i + tri_n], (int)obj_tri[i + 2 * tri_n]); 256 | tri[0] = obj_tri[i] - 1; 257 | tri[1] = obj_tri[i + tri_n] - 1; 258 | tri[2] = obj_tri[i + 2 * tri_n] - 1; 259 | index[0] = 2 * tri[0]; 260 | index[1] = index[0] + 1; 261 | index[2] = 2 * tri[1]; 262 | index[3] = index[2] + 1; 263 | index[4] = 2 * tri[2]; 264 | index[5] = index[4] + 1; 265 | tri_area = tri_areas[i]; 266 | 267 | B(0, 0) = X_g_inv[i]; 268 | B(0, 1) = X_g_inv[i + tri_n * 2]; 269 | B(1, 0) = X_g_inv[i + tri_n]; 270 | B(1, 1) = X_g_inv[i + tri_n * 3]; 271 | 272 | X_f(0, 0) = q_target[2 * tri[1]] - q_target[2 * tri[0]]; 273 | X_f(1, 0) = q_target[2 * tri[1] + 1] - q_target[2 * tri[0] + 1]; 274 | X_f(0, 1) = q_target[2 * tri[2]] - q_target[2 * tri[0]]; 275 | X_f(1, 1) = q_target[2 * tri[2] + 1] - q_target[2 * tri[0] + 1]; 276 | 277 | A = X_f * B; 278 | 279 | JacobiSVD svd(A, ComputeFullU | ComputeFullV); 280 | 281 | S = svd.singularValues(); 282 | U = svd.matrixU(); 283 | V = svd.matrixV(); 284 | 285 | bu[i] = S[0] * S[1]; 286 | 287 | es = energy_derivative(energy_type, S); 288 | 289 | cs = S; 290 | 291 | es1 = es[0]; 292 | es2 = es[1]; 293 | 294 | ///////////////////////////////////////////////////////////////////////////////////// 295 | 296 | T(0, 0) = S[0]; 297 | T(0, 1) = 0; 298 | T(1, 0) = 0; 299 | T(1, 1) = S[1]; 300 | 301 | temp_A(0, 0) = S[1]; 302 | temp_A(0, 1) = S[0]; 303 | temp_A(1, 0) = S[0]; 304 | temp_A(1, 1) = S[1]; 305 | 306 | u0 = U.col(0); 307 | u1 = U.col(1); 308 | v0 = V.col(0); 309 | v1 = V.col(1); 310 | 311 | if(abs(S[0] - S[1]) < 1e-5) 312 | { 313 | inv_A = temp_A.transpose() * temp_A + tao * II; 314 | inv_A = inv_A.inverse() * temp_A.transpose(); 315 | //mexPrintf("ill conditioned\n"); 316 | }else{ 317 | inv_A = temp_A.inverse(); 318 | } 319 | 320 | wu[i] = 0; 321 | 322 | for(int j = 0; j < 6; j++) 323 | { 324 | F_d(0, 0) = F_dot[i + j * tri_n]; 325 | F_d(0, 1) = F_dot[i + j * tri_n + 6 * 2 * tri_n]; 326 | F_d(1, 0) = F_dot[i + j * tri_n + 6 * tri_n]; 327 | F_d(1, 1) = F_dot[i + j * tri_n + 6 * 3 * tri_n]; 328 | 329 | d1 = u0.transpose() * F_d * v0; 330 | d2 = u1.transpose() * F_d * v1; 331 | 332 | dphi = d1 * es1 + d2 * es2; 333 | 334 | int cache_1 = 2 * tri[j / 2] + (j % 2); 335 | int cache_2 = x2u[cache_1]; 336 | 337 | grad[cache_1] += tri_area * dphi; 338 | 339 | if(cache_2 > 0) 340 | { 341 | int idx = cache_2 - 1; 342 | 343 | double value = d1 * cs[1] + d2 * cs[0]; 344 | 345 | J_value[idx * J_cn + (*offset)[cache_1]] = value; 346 | 347 | (*offset)[cache_1]++; 348 | 349 | JT_value[i * JT_cn + j] = value; 350 | 351 | wu[i] += value * value; 352 | } 353 | 354 | T_dot[j](0, 0) = d1; 355 | T_dot[j](0, 1) = 0; 356 | T_dot[j](1, 0) = 0; 357 | T_dot[j](1, 1) = d2; 358 | 359 | temp_w[0] = u0.transpose() * F_d * v1; 360 | temp_w[1] = -1.0 * u1.transpose() * F_d * v0; 361 | temp_w = inv_A * temp_w; 362 | 363 | w_U_dot[j](0, 0) = 0; 364 | w_U_dot[j](0, 1) = temp_w[0]; 365 | w_U_dot[j](1, 0) = -1 * temp_w[0]; 366 | w_U_dot[j](1, 1) = 0; 367 | 368 | w_V_dot[j](0, 0) = 0; 369 | w_V_dot[j](0, 1) = temp_w[1]; 370 | w_V_dot[j](1, 0) = -1 * temp_w[1]; 371 | w_V_dot[j](1, 1) = 0; 372 | } 373 | 374 | for(int j = 0; j < 6; j++) 375 | { 376 | for(int k = j; k < 6; k++) 377 | { 378 | T_ddot = w_U_dot[k].transpose() * w_U_dot[j] * T + T * w_V_dot[j] * w_V_dot[k].transpose() - w_U_dot[j] * T * w_V_dot[k] - w_U_dot[k] * T * w_V_dot[j]; 379 | 380 | value = energy_hessian(S[0], S[1], T_dot[j](0, 0), T_dot[k](0, 0), T_dot[j](1, 1), T_dot[k](1, 1), T_ddot(0, 0), T_ddot(1, 1), energy_type); 381 | 382 | ELS(j, k) = tri_area * value; 383 | ELS(k, j) = tri_area * value; 384 | 385 | row[36 * i + j * 6 + k] = index[j]; 386 | col[36 * i + j * 6 + k] = index[k]; 387 | 388 | row[36 * i + k * 6 + j] = index[k]; 389 | col[36 * i + k * 6 + j] = index[j]; 390 | } 391 | } 392 | 393 | SelfAdjointEigenSolver eig(ELS); 394 | 395 | ELS_S = eig.eigenvalues(); 396 | 397 | ELS_X = eig.eigenvectors(); 398 | 399 | for(int j = 0; j < 6; j++) 400 | { 401 | ELS_S[j] = fmax(ELS_S[j], proj_threshold); 402 | } 403 | 404 | ELS_D.diagonal() << ELS_S[0], ELS_S[1], ELS_S[2], ELS_S[3], ELS_S[4], ELS_S[5]; 405 | 406 | ELS = ELS_X * ELS_D * ELS_X.transpose(); 407 | 408 | for(int j = 0; j < 6; j++) 409 | { 410 | for(int k = j; k < 6; k++) 411 | { 412 | val[36 * i + j * 6 + k] = ELS(j, k); 413 | val[36 * i + k * 6 + j] = ELS(k, j); 414 | } 415 | } 416 | 417 | } 418 | 419 | offset->clear(); 420 | delete offset; 421 | 422 | return; 423 | 424 | } -------------------------------------------------------------------------------- /matlab-include/mex/energy_hessian_mex.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/energy_hessian_mex.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/mex/energy_value_mex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | 7 | using namespace Eigen; 8 | using namespace std; 9 | 10 | 11 | double amips_param; 12 | double c1_param; 13 | double c2_param; 14 | double d1_param; 15 | 16 | 17 | double energy_value(int type, Vector2d S) 18 | { 19 | 20 | double value = 0; 21 | double J; 22 | double l1; 23 | double l2; 24 | 25 | switch(type) 26 | { 27 | case 0: //arap 28 | value = (S[0] - 1) * (S[0] - 1) + (S[1] - 1) * (S[1] - 1); 29 | break; 30 | 31 | case 1: // mips 32 | value = S[0] / S[1] + S[1] / S[0]; 33 | //value *= 100; 34 | break; 35 | 36 | case 2: // iso 37 | value = S[0] * S[0] + 1.0 / (S[0] * S[0]) + S[1] * S[1] + 1.0 / (S[1] * S[1]); 38 | break; 39 | 40 | case 3: // amips 41 | value = exp(amips_param * (S[0] / S[1] + S[1] / S[0])); 42 | break; 43 | 44 | case 4: // conf 45 | value = S[0] / S[1]; 46 | value *= value; 47 | break; 48 | 49 | case 5: 50 | 51 | // J = S[0] * S[1]; 52 | // l1 = S[0] * S[0] + S[1] * S[1]; 53 | // l2 = S[0] * S[0] * S[1] * S[1]; 54 | // //value = (J - 1) * (J - 1); 55 | // value = c1_param * (pow(J, -2.0 / 3.0) * l1 - 3) + c2_param * (pow(J, -4.0 / 3.0) * l2 - 3) + d1_param * (J - 1) * (J - 1); 56 | // break; 57 | 58 | J = S[0] * S[1]; 59 | value = c1_param * (S[0] / S[1] + S[1] / S[0] - 2) + d1_param * (J - 1) * (J - 1); 60 | break; 61 | 62 | case 6: // olg 63 | 64 | value = max(S[0], 1.0 / S[1]); 65 | break; 66 | } 67 | 68 | return value; 69 | 70 | } 71 | 72 | 73 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 74 | { 75 | 76 | mxArray *output_mex; 77 | const int *dims; 78 | double *tri_num, *X_g_inv, *tri_areas, *obj_tri, *q_target, *type, *amips_s, *c1, *c2, *d1; 79 | double *output; 80 | 81 | tri_num = mxGetPr(prhs[0]); 82 | X_g_inv = mxGetPr(prhs[1]); 83 | tri_areas = mxGetPr(prhs[2]); 84 | obj_tri = mxGetPr(prhs[3]); 85 | q_target = mxGetPr(prhs[4]); 86 | type = mxGetPr(prhs[5]); 87 | amips_s = mxGetPr(prhs[6]); 88 | c1 = mxGetPr(prhs[7]); 89 | c2 = mxGetPr(prhs[8]); 90 | d1 = mxGetPr(prhs[9]); 91 | 92 | output_mex = plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL); 93 | 94 | output = mxGetPr(output_mex); 95 | 96 | output[0] = 0; 97 | 98 | int tri_n = tri_num[0]; 99 | int energy_type = type[0]; 100 | amips_param = amips_s[0]; 101 | c1_param = c1[0]; 102 | c2_param = c2[0]; 103 | d1_param = d1[0]; 104 | 105 | int tri[3]; 106 | double tri_area; 107 | 108 | Matrix2d B, X_f, A; 109 | Vector2d S; 110 | Matrix2d U, V; 111 | 112 | for(int i = 0; i < tri_n; i++) 113 | { 114 | //mexPrintf("%d %d %d\n", (int)obj_tri[i], (int)obj_tri[i + tri_n], (int)obj_tri[i + 2 * tri_n]); 115 | tri[0] = obj_tri[i] - 1; 116 | tri[1] = obj_tri[i + tri_n] - 1; 117 | tri[2] = obj_tri[i + 2 * tri_n] - 1; 118 | tri_area = tri_areas[i]; 119 | 120 | B(0, 0) = X_g_inv[i]; 121 | B(0, 1) = X_g_inv[i + tri_n * 2]; 122 | B(1, 0) = X_g_inv[i + tri_n]; 123 | B(1, 1) = X_g_inv[i + tri_n * 3]; 124 | 125 | X_f(0, 0) = q_target[2 * tri[1]] - q_target[2 * tri[0]]; 126 | X_f(1, 0) = q_target[2 * tri[1] + 1] - q_target[2 * tri[0] + 1]; 127 | X_f(0, 1) = q_target[2 * tri[2]] - q_target[2 * tri[0]]; 128 | X_f(1, 1) = q_target[2 * tri[2] + 1] - q_target[2 * tri[0] + 1]; 129 | 130 | A = X_f * B; 131 | 132 | JacobiSVD svd(A, ComputeFullU | ComputeFullV); 133 | 134 | S = svd.singularValues(); 135 | U = svd.matrixU(); 136 | V = svd.matrixV(); 137 | 138 | double cache = A.determinant(); 139 | 140 | if(cache <= 0) 141 | { 142 | S[1] *= -1; 143 | } 144 | 145 | double deviation = energy_value(energy_type, S); 146 | 147 | if(cache <= 0 && energy_type != 0) 148 | { 149 | mexPrintf("inverted\n"); 150 | output[0] = 1e20; 151 | break; 152 | } 153 | 154 | output[0] += tri_area * deviation; 155 | 156 | } 157 | 158 | return; 159 | 160 | } -------------------------------------------------------------------------------- /matlab-include/mex/energy_value_mex.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/energy_value_mex.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/mex/precompute_mex.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | using namespace Eigen; 9 | using namespace std; 10 | 11 | 12 | double get_tri_area(Vector2d p0, Vector2d p1, Vector2d p2) 13 | { 14 | 15 | Vector2d u = p1 - p0; 16 | Vector2d v = p2 - p0; 17 | 18 | return 0.5 * sqrt(u.dot(u) * v.dot(v) - u.dot(v) * u.dot(v)); 19 | 20 | } 21 | 22 | 23 | double get_tri_area(Vector3d p0, Vector3d p1, Vector3d p2) 24 | { 25 | 26 | Vector3d u = p1 - p0; 27 | Vector3d v = p2 - p0; 28 | 29 | return 0.5 * sqrt(u.dot(u) * v.dot(v) - u.dot(v) * u.dot(v)); 30 | 31 | } 32 | 33 | 34 | void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) 35 | { 36 | 37 | mxArray *X_g_inv_mex, *tri_areas_mex, *F_dot_mex, *row_mex, *col_mex, *val_mex, *x2u_mex, *J_mex, *J_info_mex, *JT_mex, *JT_info_mex, *perimeter_mex; 38 | 39 | double *tri_num, *tri_list, *ver_num, *ver_list, *uv_mesh, *dirichlet; 40 | double *X_g_inv, *tri_areas, *F_dot, *row, *col, *val, *x2u, *J, *J_info, *JT, *JT_info, *perimeter; 41 | 42 | tri_num = mxGetPr(prhs[0]); 43 | tri_list = mxGetPr(prhs[1]); 44 | ver_num = mxGetPr(prhs[2]); 45 | ver_list = mxGetPr(prhs[3]); 46 | uv_mesh = mxGetPr(prhs[4]); 47 | dirichlet = mxGetPr(prhs[5]); 48 | 49 | int tri_n = tri_num[0]; 50 | int ver_n = ver_num[0]; 51 | int is_uv_mesh = uv_mesh[0]; 52 | 53 | X_g_inv_mex = plhs[0] = mxCreateDoubleMatrix(4 * tri_n, 1, mxREAL); 54 | tri_areas_mex = plhs[1] = mxCreateDoubleMatrix(tri_n, 1, mxREAL); 55 | F_dot_mex = plhs[2] = mxCreateDoubleMatrix(24 * tri_n, 1, mxREAL); 56 | row_mex = plhs[3] = mxCreateDoubleMatrix(18 * tri_n, 1, mxREAL); 57 | col_mex = plhs[4] = mxCreateDoubleMatrix(18 * tri_n, 1, mxREAL); 58 | val_mex = plhs[5] = mxCreateDoubleMatrix(18 * tri_n, 1, mxREAL); 59 | x2u_mex = plhs[6] = mxCreateDoubleMatrix(2 * ver_n, 1, mxREAL); 60 | 61 | X_g_inv = mxGetPr(X_g_inv_mex); 62 | tri_areas = mxGetPr(tri_areas_mex); 63 | F_dot = mxGetPr(F_dot_mex); 64 | row = mxGetPr(row_mex); 65 | col = mxGetPr(col_mex); 66 | val = mxGetPr(val_mex); 67 | x2u = mxGetPr(x2u_mex); 68 | 69 | int count = 1; 70 | int fixed_num = 0; 71 | int tri[3]; 72 | 73 | for(int i = 0; i < 2 * ver_n; i++) 74 | { 75 | if(dirichlet[i] == 0) 76 | { 77 | x2u[i] = count; 78 | count++; 79 | }else 80 | { 81 | fixed_num++; 82 | x2u[i] = 0; 83 | } 84 | } 85 | 86 | //mexPrintf("check 1\n"); 87 | 88 | vector*> ver_tri_map; 89 | 90 | for(int i = 0; i < ver_n; i++) 91 | { 92 | vector* tris = new vector(); 93 | ver_tri_map.push_back(tris); 94 | } 95 | 96 | for(int i = 0; i < tri_n; i++) 97 | { 98 | tri[0] = tri_list[i] - 1; 99 | tri[1] = tri_list[i + tri_n] - 1; 100 | tri[2] = tri_list[i + 2 * tri_n] - 1; 101 | 102 | ver_tri_map[tri[0]]->push_back(i); 103 | ver_tri_map[tri[1]]->push_back(i); 104 | ver_tri_map[tri[2]]->push_back(i); 105 | } 106 | 107 | int max_valence = 0; 108 | 109 | for(int i = 0; i < ver_n; i++) 110 | { 111 | if(max_valence < ver_tri_map[i]->size()) 112 | { 113 | max_valence = ver_tri_map[i]->size(); 114 | } 115 | } 116 | 117 | J_mex = plhs[7] = mxCreateDoubleMatrix((2 * ver_n - fixed_num) * max_valence, 1, mxREAL); 118 | J_info_mex = plhs[8] = mxCreateDoubleMatrix(2, 1, mxREAL); 119 | JT_mex = plhs[9] = mxCreateDoubleMatrix(tri_n * 3 * 2, 1, mxREAL); 120 | JT_info_mex = plhs[10] = mxCreateDoubleMatrix(2, 1, mxREAL); 121 | perimeter_mex = plhs[11] = mxCreateDoubleMatrix(ver_n, 1, mxREAL); 122 | 123 | J = mxGetPr(J_mex); 124 | J_info = mxGetPr(J_info_mex); 125 | JT = mxGetPr(JT_mex); 126 | JT_info = mxGetPr(JT_info_mex); 127 | perimeter = mxGetPr(perimeter_mex); 128 | 129 | count = 0; 130 | 131 | J_info[0] = 2 * ver_n - fixed_num; 132 | J_info[1] = max_valence; 133 | 134 | for(int i = 0; i < ver_n; i++) 135 | { 136 | perimeter[i] = 0; 137 | 138 | if(dirichlet[2 * i] == 0) 139 | { 140 | for(int j = 0; j < max_valence; j++) 141 | { 142 | if(j < ver_tri_map[i]->size()) 143 | { 144 | J[count * max_valence + j] = ver_tri_map[i]->at(j); 145 | }else{ 146 | J[count * max_valence + j] = -1; 147 | } 148 | } 149 | 150 | count++; 151 | 152 | for(int j = 0; j < max_valence; j++) 153 | { 154 | if(j < ver_tri_map[i]->size()) 155 | { 156 | J[count * max_valence + j] = ver_tri_map[i]->at(j); 157 | }else{ 158 | J[count * max_valence + j] = -1; 159 | } 160 | } 161 | 162 | count++; 163 | } 164 | } 165 | 166 | 167 | JT_info[0] = tri_n; 168 | JT_info[1] = 3 * 2; 169 | 170 | for(int i = 0; i < tri_n; i++) 171 | { 172 | tri[0] = tri_list[i] - 1; 173 | tri[1] = tri_list[i + tri_n] - 1; 174 | tri[2] = tri_list[i + 2 * tri_n] - 1; 175 | 176 | for(int j = 0; j < 3; j++) 177 | { 178 | if(x2u[2 * tri[j]] > 0) 179 | { 180 | JT[i * 2 * 3 + 2 * j + 0] = x2u[2 * tri[j] + 0] - 1; 181 | JT[i * 2 * 3 + 2 * j + 1] = x2u[2 * tri[j] + 1] - 1; 182 | }else{ 183 | JT[i * 2 * 3 + 2 * j + 0] = -1; 184 | JT[i * 2 * 3 + 2 * j + 1] = -1; 185 | } 186 | } 187 | } 188 | 189 | for(int i = 0; i < ver_n; i++) 190 | { 191 | ver_tri_map[i]->clear(); 192 | delete ver_tri_map[i]; 193 | } 194 | 195 | ver_tri_map.clear(); 196 | 197 | /////////////////////////////////////////////////////////////////////// 198 | 199 | Matrix2d X_g, B; 200 | 201 | double C_sub[4][6]; 202 | 203 | double tri_area; 204 | 205 | for (int i = 0; i < 4; i++) 206 | { 207 | for (int j = 0; j < 6; j++) 208 | { 209 | C_sub[i][j] = 0; 210 | } 211 | } 212 | 213 | for(int i = 0; i < tri_n; i++) 214 | { 215 | 216 | tri[0] = tri_list[i] - 1; 217 | tri[1] = tri_list[i + tri_n] - 1; 218 | tri[2] = tri_list[i + 2 * tri_n] - 1; 219 | 220 | ///////////////////////////////////////////////////////////// 221 | 222 | if(is_uv_mesh) 223 | { 224 | 225 | Vector3d p0(ver_list[3 * tri[0]], ver_list[3 * tri[0] + 1], ver_list[3 * tri[0] + 2]); 226 | Vector3d p1(ver_list[3 * tri[1]], ver_list[3 * tri[1] + 1], ver_list[3 * tri[1] + 2]); 227 | Vector3d p2(ver_list[3 * tri[2]], ver_list[3 * tri[2] + 1], ver_list[3 * tri[2] + 2]); 228 | 229 | perimeter[tri[0]] += (p1 - p2).norm(); 230 | perimeter[tri[1]] += (p2 - p0).norm(); 231 | perimeter[tri[2]] += (p0 - p1).norm(); 232 | 233 | tri_area = tri_areas[i] = get_tri_area(p0, p1, p2); 234 | 235 | Vector3d bx = p1 - p0; 236 | Vector3d cx = p2 - p0; 237 | 238 | Vector3d Ux = bx; 239 | Ux.normalize(); 240 | 241 | Vector3d w = Ux.cross(cx); 242 | Vector3d Wx = w; 243 | Wx.normalize(); 244 | 245 | Vector3d Vx = Ux.cross(Wx); 246 | 247 | Matrix3d R; 248 | R.col(0) = Ux; 249 | R.col(1) = Vx; 250 | R.col(2) = Wx; 251 | 252 | Vector3d vb = R.transpose() * bx; 253 | Vector3d vc = R.transpose() * cx; 254 | 255 | X_g << vb[0], vc[0], vb[1], vc[1]; 256 | 257 | if(X_g.determinant() < 0) 258 | { 259 | X_g.row(1) = -1.0 * X_g.row(1); 260 | } 261 | 262 | }else{ 263 | 264 | Vector2d p0(ver_list[2 * tri[0]], ver_list[2 * tri[0] + 1]); 265 | Vector2d p1(ver_list[2 * tri[1]], ver_list[2 * tri[1] + 1]); 266 | Vector2d p2(ver_list[2 * tri[2]], ver_list[2 * tri[2] + 1]); 267 | 268 | perimeter[tri[0]] += (p1 - p2).norm(); 269 | perimeter[tri[1]] += (p2 - p0).norm(); 270 | perimeter[tri[2]] += (p0 - p1).norm(); 271 | 272 | tri_area = tri_areas[i] = get_tri_area(p0, p1, p2); 273 | 274 | Vector2d e0 = p1 - p0; 275 | Vector2d e1 = p2 - p0; 276 | 277 | X_g << e0[0], e1[0], e0[1], e1[1]; 278 | 279 | } 280 | 281 | /////////////////////////////////////////////////////////////// 282 | 283 | B = X_g.inverse(); 284 | 285 | X_g_inv[i] = B(0, 0); 286 | X_g_inv[tri_n + i] = B(1, 0); 287 | X_g_inv[2 * tri_n + i] = B(0, 1); 288 | X_g_inv[3 * tri_n + i] = B(1, 1); 289 | 290 | C_sub[0][0] = -(B(0, 0) + B(1, 0)); 291 | C_sub[1][1] = -(B(0, 0) + B(1, 0)); 292 | C_sub[0][2] = B(0, 0); 293 | C_sub[1][3] = B(0, 0); 294 | C_sub[0][4] = B(1, 0); 295 | C_sub[1][5] = B(1, 0); 296 | 297 | C_sub[2][0] = -(B(0, 1) + B(1, 1)); 298 | C_sub[3][1] = -(B(0, 1) + B(1, 1)); 299 | C_sub[2][2] = B(0, 1); 300 | C_sub[3][3] = B(0, 1); 301 | C_sub[2][4] = B(1, 1); 302 | C_sub[3][5] = B(1, 1); 303 | 304 | for(int j = 0; j < 6; j++) 305 | { 306 | F_dot[0 * tri_n * 6 + j * tri_n + i] = C_sub[0][j]; 307 | F_dot[1 * tri_n * 6 + j * tri_n + i] = C_sub[1][j]; 308 | F_dot[2 * tri_n * 6 + j * tri_n + i] = C_sub[2][j]; 309 | F_dot[3 * tri_n * 6 + j * tri_n + i] = C_sub[3][j]; 310 | } 311 | 312 | ////////////////////////////////////////////////////////////////////// 313 | 314 | Matrix2d A0; 315 | A0 << -1.0 * (B(0, 0) + B(1, 0)), 0, 0, -1.0 * (B(0, 0) + B(1, 0)); 316 | Matrix2d A1; 317 | A1 << -1.0 * (B(0, 1) + B(1, 1)), 0, 0, -1.0 * (B(0, 1) + B(1, 1)); 318 | Matrix2d B0; 319 | B0 << B(0, 0), 0, 0, B(0, 0); 320 | Matrix2d B1; 321 | B1 << B(0, 1), 0, 0, B(0, 1); 322 | Matrix2d C0; 323 | C0 << B(1, 0), 0, 0, B(1, 0); 324 | Matrix2d C1; 325 | C1 << B(1, 1), 0, 0, B(1, 1); 326 | 327 | Matrix2d AA = A0 * A0 + A1 * A1; 328 | Matrix2d AB = A0 * B0 + A1 * B1; 329 | Matrix2d AC = A0 * C0 + A1 * C1; 330 | Matrix2d BA = B0 * A0 + B1 * A1; 331 | Matrix2d BB = B0 * B0 + B1 * B1; 332 | Matrix2d BC = B0 * C0 + B1 * C1; 333 | Matrix2d CA = C0 * A0 + C1 * A1; 334 | Matrix2d CB = C0 * B0 + C1 * B1; 335 | Matrix2d CC = C0 * C0 + C1 * C1; 336 | 337 | row[18 * i + 0] = 2 * tri[0]; 338 | col[18 * i + 0] = 2 * tri[0]; 339 | val[18 * i + 0] = AA(0, 0) * tri_area; 340 | 341 | row[18 * i + 1] = 2 * tri[0] + 1; 342 | col[18 * i + 1] = 2 * tri[0] + 1; 343 | val[18 * i + 1] = AA(1, 1) * tri_area; 344 | 345 | row[18 * i + 2] = 2 * tri[0]; 346 | col[18 * i + 2] = 2 * tri[1]; 347 | val[18 * i + 2] = AB(0, 0) * tri_area; 348 | 349 | row[18 * i + 3] = 2 * tri[0] + 1; 350 | col[18 * i + 3] = 2 * tri[1] + 1; 351 | val[18 * i + 3] = AB(1, 1) * tri_area; 352 | 353 | row[18 * i + 4] = 2 * tri[0]; 354 | col[18 * i + 4] = 2 * tri[2]; 355 | val[18 * i + 4] = AC(0, 0) * tri_area; 356 | 357 | row[18 * i + 5] = 2 * tri[0] + 1; 358 | col[18 * i + 5] = 2 * tri[2] + 1; 359 | val[18 * i + 5] = AC(1, 1) * tri_area; 360 | 361 | row[18 * i + 6] = 2 * tri[1]; 362 | col[18 * i + 6] = 2 * tri[0]; 363 | val[18 * i + 6] = BA(0, 0) * tri_area; 364 | 365 | row[18 * i + 7] = 2 * tri[1] + 1; 366 | col[18 * i + 7] = 2 * tri[0] + 1; 367 | val[18 * i + 7] = BA(1, 1) * tri_area; 368 | 369 | row[18 * i + 8] = 2 * tri[1]; 370 | col[18 * i + 8] = 2 * tri[1]; 371 | val[18 * i + 8] = BB(0, 0) * tri_area; 372 | 373 | row[18 * i + 9] = 2 * tri[1] + 1; 374 | col[18 * i + 9] = 2 * tri[1] + 1; 375 | val[18 * i + 9] = BB(1, 1) * tri_area; 376 | 377 | row[18 * i + 10] = 2 * tri[1]; 378 | col[18 * i + 10] = 2 * tri[2]; 379 | val[18 * i + 10] = BC(0, 0) * tri_area; 380 | 381 | row[18 * i + 11] = 2 * tri[1] + 1; 382 | col[18 * i + 11] = 2 * tri[2] + 1; 383 | val[18 * i + 11] = BC(1, 1) * tri_area; 384 | 385 | row[18 * i + 12] = 2 * tri[2]; 386 | col[18 * i + 12] = 2 * tri[0]; 387 | val[18 * i + 12] = CA(0, 0) * tri_area; 388 | 389 | row[18 * i + 13] = 2 * tri[2] + 1; 390 | col[18 * i + 13] = 2 * tri[0] + 1; 391 | val[18 * i + 13] = CA(1, 1) * tri_area; 392 | 393 | row[18 * i + 14] = 2 * tri[2]; 394 | col[18 * i + 14] = 2 * tri[1]; 395 | val[18 * i + 14] = CB(0, 0) * tri_area; 396 | 397 | row[18 * i + 15] = 2 * tri[2] + 1; 398 | col[18 * i + 15] = 2 * tri[1] + 1; 399 | val[18 * i + 15] = CB(1, 1) * tri_area; 400 | 401 | row[18 * i + 16] = 2 * tri[2]; 402 | col[18 * i + 16] = 2 * tri[2]; 403 | val[18 * i + 16] = CC(0, 0) * tri_area; 404 | 405 | row[18 * i + 17] = 2 * tri[2] + 1; 406 | col[18 * i + 17] = 2 * tri[2] + 1; 407 | val[18 * i + 17] = CC(1, 1) * tri_area; 408 | 409 | } 410 | 411 | return; 412 | 413 | } -------------------------------------------------------------------------------- /matlab-include/mex/precompute_mex.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/precompute_mex.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/mex/read_3d_bone_anim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | using namespace Eigen; 18 | using namespace std; 19 | 20 | void euler_to_quat(const Eigen::Vector3d& euler, Eigen::Quaterniond& q) { 21 | 22 | q = Eigen::AngleAxisd(euler(2), Eigen::Vector3d::UnitZ()) 23 | * Eigen::AngleAxisd(euler(1), Eigen::Vector3d::UnitY()) 24 | * Eigen::AngleAxisd(euler(0), Eigen::Vector3d::UnitX()); 25 | } 26 | 27 | 28 | void euler_to_quat(const Eigen::Vector3d& euler, const Eigen::Affine3d& a, Eigen::Quaterniond& q) { 29 | q = Eigen::AngleAxisd(euler(2), a.rotation().col(2)) 30 | * Eigen::AngleAxisd(euler(1), a.rotation().col(1)) 31 | * Eigen::AngleAxisd(euler(0), a.rotation().col(0)); 32 | } 33 | 34 | 35 | void read_bone_anim(std::string anim_file, 36 | const Eigen::MatrixXd& C, 37 | const Eigen::MatrixXi& BE, 38 | const Eigen::VectorXi& P, 39 | std::vector& T_list) 40 | { 41 | FILE* file; 42 | file= fopen(anim_file.c_str(), "rb"); 43 | 44 | double degree2radian = igl::PI/180.0; 45 | 46 | int num_bone, num_frame; 47 | double val = 0; 48 | 49 | typedef std::vector > RotationList; 51 | 52 | 53 | fscanf(file, "%d %d\n", &num_bone, &num_frame); 54 | T_list.resize(num_frame); 55 | RotationList rot_list(num_bone); 56 | std::vector tran_list(num_bone); 57 | std::vector rest_list(num_bone); 58 | 59 | Eigen::Vector3d root_rest_tran; 60 | Eigen::Affine3d root_affine; 61 | for (int j = 0; j < 3; j++) { 62 | fscanf(file, "%lf", &val); 63 | root_rest_tran(j) = val; 64 | } 65 | Eigen::Vector3d euler; 66 | for (int j = 0; j < 3; j++) { 67 | fscanf(file, "%lf", &val); 68 | euler(j) = val; 69 | } 70 | euler = euler.array() * degree2radian; 71 | Eigen::Quaterniond q; 72 | euler_to_quat(euler, q); 73 | root_affine = Eigen::Affine3d::Identity(); 74 | root_affine.rotate(q); 75 | 76 | for (int i = 0; i < num_bone; i++) { 77 | Eigen::Vector3d euler; 78 | for (int j = 0; j < 3; j++) { 79 | fscanf(file, "%lf", &val); 80 | euler(j) = val; 81 | } 82 | euler = euler.array() * degree2radian; 83 | Eigen::Quaterniond q; 84 | euler_to_quat(euler, q); 85 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 86 | a.rotate(q); 87 | rest_list[i] = a; 88 | } 89 | //Eigen::Affine3d root_affine = rest_list[0]; 90 | Eigen::Vector3d root_tran, root_rot; 91 | for (int k = 0; k < num_frame; k++) { 92 | for (int j = 0; j < 3; j++) { 93 | fscanf(file, "%lf", &val); 94 | root_rot(j) = val; 95 | } 96 | for (int j = 0; j < 3; j++) { 97 | fscanf(file, "%lf", &val); 98 | root_tran(j) = val; 99 | } 100 | root_rot = root_rot.array() * degree2radian; 101 | Eigen::Quaterniond root_q; 102 | euler_to_quat(root_rot, root_affine, root_q); 103 | 104 | for (int i = 0; i < num_bone; i++) { 105 | Eigen::Vector3d euler; 106 | for (int j = 0; j < 3; j++) { 107 | fscanf(file, "%lf", &val); 108 | euler(j) = val; 109 | } 110 | euler = euler.array() * degree2radian; 111 | Eigen::Quaterniond q; 112 | euler_to_quat(euler, rest_list[i], q); 113 | 114 | if(P(i)==-1){ 115 | int root_cnt = 0; 116 | for(int ii=0; ii1) 120 | q = q*root_q; 121 | tran_list[i] = root_tran - root_rest_tran; 122 | } 123 | else 124 | tran_list[i] = Eigen::Vector3d::Zero(); 125 | rot_list[i] = q; 126 | } 127 | RotationList vQ; 128 | std::vector vT; 129 | igl::forward_kinematics(C, BE, P, rot_list, tran_list, vQ, vT); 130 | 131 | Eigen::MatrixXd T(num_bone * 4, 3); 132 | for (int i = 0; i < num_bone; i++) { 133 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 134 | a.translate(vT[i]); 135 | a.rotate(vQ[i]); 136 | T.block(i * 4, 0, 4, 3) = a.matrix().transpose().block(0, 0, 4, 3); 137 | } 138 | T_list[k] = T; 139 | } 140 | fclose(file); 141 | } 142 | 143 | void read_bone_anim(std::string anim_file, 144 | const Eigen::MatrixXd& C, 145 | const Eigen::MatrixXi& BE, 146 | const Eigen::VectorXi& P, 147 | const Eigen::VectorXd& center, 148 | const double& scale, 149 | std::vector& T_list) 150 | { 151 | FILE* file; 152 | file= fopen(anim_file.c_str(), "rb"); 153 | 154 | double degree2radian = igl::PI/180.0; 155 | 156 | int num_bone, num_frame; 157 | double val = 0; 158 | 159 | typedef std::vector > RotationList; 161 | 162 | 163 | fscanf(file, "%d %d\n", &num_bone, &num_frame); 164 | T_list.resize(num_frame); 165 | RotationList rot_list(num_bone); 166 | std::vector tran_list(num_bone); 167 | std::vector rest_list(num_bone); 168 | 169 | Eigen::Vector3d root_rest_tran; 170 | Eigen::Affine3d root_affine; 171 | for (int j = 0; j < 3; j++) { 172 | fscanf(file, "%lf", &val); 173 | root_rest_tran(j) = val; 174 | } 175 | root_rest_tran = (root_rest_tran-center)/scale; 176 | 177 | Eigen::Vector3d euler; 178 | for (int j = 0; j < 3; j++) { 179 | fscanf(file, "%lf", &val); 180 | euler(j) = val; 181 | } 182 | euler = euler.array() * degree2radian; 183 | Eigen::Quaterniond q; 184 | euler_to_quat(euler, q); 185 | root_affine = Eigen::Affine3d::Identity(); 186 | root_affine.rotate(q); 187 | 188 | for (int i = 0; i < num_bone; i++) { 189 | Eigen::Vector3d euler; 190 | for (int j = 0; j < 3; j++) { 191 | fscanf(file, "%lf", &val); 192 | euler(j) = val; 193 | } 194 | euler = euler.array() * degree2radian; 195 | Eigen::Quaterniond q; 196 | euler_to_quat(euler, q); 197 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 198 | a.rotate(q); 199 | rest_list[i] = a; 200 | } 201 | //Eigen::Affine3d root_affine = rest_list[0]; 202 | Eigen::Vector3d root_tran, root_rot; 203 | for (int k = 0; k < num_frame; k++) { 204 | for (int j = 0; j < 3; j++) { 205 | fscanf(file, "%lf", &val); 206 | root_rot(j) = val; 207 | } 208 | for (int j = 0; j < 3; j++) { 209 | fscanf(file, "%lf", &val); 210 | root_tran(j) = val; 211 | } 212 | root_tran = (root_tran - center)/scale; 213 | root_rot = root_rot.array() * degree2radian; 214 | Eigen::Quaterniond root_q; 215 | euler_to_quat(root_rot, root_affine, root_q); 216 | 217 | for (int i = 0; i < num_bone; i++) { 218 | Eigen::Vector3d euler; 219 | for (int j = 0; j < 3; j++) { 220 | fscanf(file, "%lf", &val); 221 | euler(j) = val; 222 | } 223 | euler = euler.array() * degree2radian; 224 | Eigen::Quaterniond q; 225 | euler_to_quat(euler, rest_list[i], q); 226 | 227 | if(P(i)==-1){ 228 | int root_cnt = 0; 229 | for(int ii=0; ii1) 233 | q = q*root_q; 234 | tran_list[i] = root_tran - root_rest_tran; 235 | } 236 | else 237 | tran_list[i] = Eigen::Vector3d::Zero(); 238 | rot_list[i] = q; 239 | } 240 | RotationList vQ; 241 | std::vector vT; 242 | igl::forward_kinematics(C, BE, P, rot_list, tran_list, vQ, vT); 243 | 244 | Eigen::MatrixXd T(num_bone * 4, 3); 245 | for (int i = 0; i < num_bone; i++) { 246 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 247 | a.translate(vT[i]); 248 | a.rotate(vQ[i]); 249 | T.block(i * 4, 0, 4, 3) = a.matrix().transpose().block(0, 0, 4, 3); 250 | } 251 | T_list[k] = T; 252 | 253 | } 254 | fclose(file); 255 | } 256 | 257 | 258 | 259 | void mexFunction( 260 | int nlhs, 261 | mxArray *plhs[], 262 | int nrhs, 263 | const mxArray *prhs[]) 264 | { 265 | Eigen::MatrixXd C; 266 | Eigen::MatrixXi BE; 267 | Eigen::VectorXi P; 268 | Eigen::VectorXd center; 269 | double scale; 270 | char* anim_file = mxArrayToString(prhs[0]); 271 | 272 | igl::matlab::parse_rhs_double(prhs+1, C); 273 | igl::matlab::parse_rhs_index(prhs+2, BE); 274 | 275 | igl::matlab::parse_rhs_double(prhs+3, center); 276 | scale = (double) *mxGetPr(prhs[4]); 277 | 278 | igl::directed_edge_parents(BE, P); 279 | 280 | std::vector T_list; 281 | read_bone_anim(anim_file, C,BE,P,center,scale, T_list); 282 | //read_bone_anim(anim_file, C,BE,P, T_list); 283 | 284 | 285 | plhs[0] = mxCreateCellMatrix(T_list.size(),1); 286 | 287 | mxArray *x; 288 | for(int i=0; i > map(mxGetPr(x),m,n); 293 | map = T_list[i].template cast(); 294 | mxSetCell(plhs[0], i, x); 295 | } 296 | return; 297 | } -------------------------------------------------------------------------------- /matlab-include/mex/read_3d_bone_anim.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/read_3d_bone_anim.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/mex/read_3d_pnt_anim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | 17 | using namespace Eigen; 18 | using namespace std; 19 | 20 | void euler_to_quat(const Eigen::Vector3d& euler, Eigen::Quaterniond& q) { 21 | 22 | q = Eigen::AngleAxisd(euler(2), Eigen::Vector3d::UnitZ()) 23 | * Eigen::AngleAxisd(euler(1), Eigen::Vector3d::UnitY()) 24 | * Eigen::AngleAxisd(euler(0), Eigen::Vector3d::UnitX()); 25 | } 26 | 27 | 28 | void euler_to_quat(const Eigen::Vector3d& euler, const Eigen::Affine3d& a, Eigen::Quaterniond& q) { 29 | q = Eigen::AngleAxisd(euler(2), a.rotation().col(2)) 30 | * Eigen::AngleAxisd(euler(1), a.rotation().col(1)) 31 | * Eigen::AngleAxisd(euler(0), a.rotation().col(0)); 32 | // q = Eigen::AngleAxisd(euler(0), a.rotation().col(0)) 33 | // * Eigen::AngleAxisd(euler(1), a.rotation().col(1)) 34 | // * Eigen::AngleAxisd(euler(2), a.rotation().col(2)); 35 | } 36 | 37 | 38 | void read_pnt_anim(std::string anim_file, 39 | const Eigen::MatrixXd& C, 40 | const Eigen::VectorXd& center, 41 | const double& scale, 42 | std::vector& T_list) 43 | { 44 | FILE* file; 45 | file= fopen(anim_file.c_str(), "rb"); 46 | 47 | int dim = 3;//= C.cols(); 48 | 49 | double degree2radian = igl::PI/180.0; 50 | 51 | int num_bone, num_frame; 52 | double val = 0; 53 | 54 | typedef std::vector > RotationList; 56 | 57 | 58 | fscanf(file, "%d %d\n", &num_bone, &num_frame); 59 | T_list.resize(num_frame); 60 | //std::cout<<"num_bone: "< rest_tran_list(num_bone); 63 | std::vector rest_affine_list(num_bone); 64 | 65 | for(int i=0; i tran_list(num_bone); 88 | 89 | for (int k = 0; k < num_frame; k++) { 90 | for (int i = 0; i < num_bone; i++) { 91 | Eigen::Vector3d tran; 92 | for (int j = 0; j < dim; j++) { 93 | fscanf(file, "%lf", &val); 94 | tran(j) = val; 95 | } 96 | tran = (tran - center)/scale; 97 | Eigen::Vector3d euler; 98 | for (int j = 0; j < dim; j++) { 99 | fscanf(file, "%lf", &val); 100 | euler(j) = val; 101 | } 102 | euler = euler.array() * degree2radian; 103 | Eigen::Quaterniond q; 104 | euler_to_quat(euler, rest_affine_list[i], q); 105 | //std::cout<<"1 i: "< vT= tran_list; 121 | //igl::forward_kinematics(C, BE, P, rot_list, tran_list, vQ, vT); 122 | 123 | Eigen::MatrixXd T(num_bone * (dim+1), dim); 124 | for (int i = 0; i < num_bone; i++) { 125 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 126 | a.translate(vT[i]); 127 | a.rotate(vQ[i]); 128 | T.block(i * (dim+1), 0, dim+1, dim) = a.matrix().transpose().block(0, 0, dim+1, dim); 129 | } 130 | T_list[k] = T; 131 | } 132 | fclose(file); 133 | 134 | } 135 | 136 | 137 | // void read_pnt_anim(std::string anim_file, 138 | // std::vector& T_list) 139 | // { 140 | // FILE* file; 141 | // file= fopen(anim_file.c_str(), "rb"); 142 | 143 | // int dim = 3;//= C.cols(); 144 | 145 | // double degree2radian = igl::PI/180.0; 146 | 147 | // int num_bone, num_frame; 148 | // double val = 0; 149 | 150 | // typedef std::vector > RotationList; 152 | 153 | 154 | // fscanf(file, "%d %d\n", &num_bone, &num_frame); 155 | // T_list.resize(num_frame); 156 | // //std::cout<<"num_bone: "< rest_tran_list(num_bone); 159 | // std::vector rest_affine_list(num_bone); 160 | 161 | // for(int i=0; i tran_list(num_bone); 183 | 184 | // for (int k = 0; k < num_frame; k++) { 185 | // for (int i = 0; i < num_bone; i++) { 186 | // Eigen::Vector3d tran; 187 | // for (int j = 0; j < dim; j++) { 188 | // fscanf(file, "%lf", &val); 189 | // tran(j) = val; 190 | // } 191 | // Eigen::Vector3d euler; 192 | // for (int j = 0; j < dim; j++) { 193 | // fscanf(file, "%lf", &val); 194 | // euler(j) = val; 195 | // } 196 | // euler = euler.array() * degree2radian; 197 | // Eigen::Quaterniond q; 198 | // euler_to_quat(euler, rest_affine_list[i], q); 199 | 200 | // tran_list[i] = tran - rest_tran_list[i]; 201 | // rot_list[i] = q; 202 | // } 203 | // RotationList vQ = rot_list; 204 | // std::vector vT= tran_list; 205 | // //igl::forward_kinematics(C, BE, P, rot_list, tran_list, vQ, vT); 206 | 207 | // Eigen::MatrixXd T(num_bone * (dim+1), dim); 208 | // for (int i = 0; i < num_bone; i++) { 209 | // Eigen::Affine3d a = Eigen::Affine3d::Identity(); 210 | // a.translate(vT[i]); 211 | // a.rotate(vQ[i]); 212 | // T.block(i * (dim+1), 0, dim+1, dim) = a.matrix().transpose().block(0, 0, dim+1, dim); 213 | // } 214 | // T_list[k] = T; 215 | // } 216 | // fclose(file); 217 | // } 218 | 219 | void read_pnt_anim(std::string anim_file, 220 | Eigen::MatrixXd C, 221 | std::vector& T_list) 222 | { 223 | FILE* file; 224 | file= fopen(anim_file.c_str(), "rb"); 225 | 226 | int dim = 3;//= C.cols(); 227 | 228 | double degree2radian = igl::PI/180.0; 229 | 230 | int num_bone, num_frame; 231 | double val = 0; 232 | 233 | typedef std::vector > RotationList; 235 | 236 | 237 | fscanf(file, "%d %d\n", &num_bone, &num_frame); 238 | T_list.resize(num_frame); 239 | //std::cout<<"num_bone: "< rest_tran_list(num_bone); 242 | std::vector rest_affine_list(num_bone); 243 | 244 | for(int i=0; i tran_list(num_bone); 266 | 267 | for (int k = 0; k < num_frame; k++) { 268 | for (int i = 0; i < num_bone; i++) { 269 | Eigen::Vector3d tran; 270 | for (int j = 0; j < dim; j++) { 271 | fscanf(file, "%lf", &val); 272 | tran(j) = val; 273 | } 274 | Eigen::Vector3d euler; 275 | for (int j = 0; j < dim; j++) { 276 | fscanf(file, "%lf", &val); 277 | euler(j) = val; 278 | } 279 | euler = euler.array() * degree2radian; 280 | Eigen::Quaterniond q; 281 | euler_to_quat(euler, rest_affine_list[i], q); 282 | 283 | q = rest_affine_list[i].rotation().transpose()*q; 284 | 285 | const Eigen::Vector3d cn = C.row(i).transpose(); 286 | 287 | tran_list[i] = tran - rest_tran_list[i] + cn-q*cn; 288 | rot_list[i] = q;//cn-q*cn;//q; 289 | } 290 | RotationList vQ = rot_list; 291 | std::vector vT= tran_list; 292 | //igl::forward_kinematics(C, BE, P, rot_list, tran_list, vQ, vT); 293 | 294 | Eigen::MatrixXd T(num_bone * (dim+1), dim); 295 | for (int i = 0; i < num_bone; i++) { 296 | Eigen::Affine3d a = Eigen::Affine3d::Identity(); 297 | a.translate(vT[i]); 298 | a.rotate(vQ[i]); 299 | T.block(i * (dim+1), 0, dim+1, dim) = a.matrix().transpose().block(0, 0, dim+1, dim); 300 | } 301 | T_list[k] = T; 302 | } 303 | fclose(file); 304 | } 305 | 306 | 307 | void mexFunction( 308 | int nlhs, 309 | mxArray *plhs[], 310 | int nrhs, 311 | const mxArray *prhs[]) 312 | { 313 | Eigen::MatrixXd C; 314 | Eigen::MatrixXi BE; 315 | Eigen::VectorXi P; 316 | Eigen::VectorXd center; 317 | double scale; 318 | char* anim_file = mxArrayToString(prhs[0]); 319 | 320 | igl::matlab::parse_rhs_double(prhs+1, C); 321 | igl::matlab::parse_rhs_double(prhs+2, center); 322 | scale = (double) *mxGetPr(prhs[3]); 323 | 324 | 325 | 326 | 327 | std::vector T_list; 328 | //read_pnt_anim(anim_file, center, scale, T_list); 329 | //read_pnt_anim(anim_file, C, T_list); 330 | read_pnt_anim(anim_file, C, center, scale, T_list); 331 | 332 | 333 | plhs[0] = mxCreateCellMatrix(T_list.size(),1); 334 | 335 | mxArray *x; 336 | for(int i=0; i > map(mxGetPr(x),m,n); 341 | map = T_list[i].template cast(); 342 | mxSetCell(plhs[0], i, x); 343 | } 344 | return; 345 | } -------------------------------------------------------------------------------- /matlab-include/mex/read_3d_pnt_anim.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/read_3d_pnt_anim.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/mex/read_blendshape_anim.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | 20 | #include 21 | 22 | using namespace Eigen; 23 | using namespace std; 24 | 25 | void read_mesh_files_from_directory(const std::string& directory, std::vector& mesh_list){ 26 | 27 | using namespace std; 28 | 29 | std::vector file_list; 30 | 31 | DIR *d; 32 | struct dirent *dir; 33 | int i=0; 34 | d = opendir(directory.c_str()); 35 | if (d) 36 | { 37 | while ((dir = readdir(d)) != NULL) 38 | { 39 | i++; 40 | file_list.push_back(dir->d_name); 41 | } 42 | closedir(d); 43 | } 44 | for(int i=0; i& name_list, 58 | std::vector& V_list) 59 | { 60 | FILE* file; 61 | file= fopen(list_file.c_str(), "rb"); 62 | int num_list; 63 | fscanf(file, "%d\n", &num_list); 64 | 65 | 66 | std::vector reordered_id(num_list); 67 | for(int i=0; i reorder_name_list(num_list); 80 | for(int i=0; i& w_list) 102 | { 103 | FILE* file; 104 | file= fopen(anim_file.c_str(), "rb"); 105 | int num_bs, num_frame; 106 | fscanf(file, "%d %d\n", &num_bs, &num_frame); 107 | 108 | w_list.resize(num_frame); 109 | for(int i=0; i& BV_list, 125 | //Eigen::RowVectorXd Vcenter, double Vbound, 126 | Eigen::SparseMatrix& BS) 127 | { 128 | Eigen::MatrixXd VT = V.transpose(); 129 | Eigen::VectorXd VCol(Eigen::Map(VT.data(), V.cols()*V.rows())); 130 | std::vector > coefficients; 131 | for(int j=0; j(BVT.data(), BV.cols()*BV.rows()); 139 | 140 | Eigen::VectorXd deltaV = bVcol-VCol; 141 | for(int i=0; i1e-12){ 143 | coefficients.push_back(Eigen::Triplet(i,j, deltaV(i))); 144 | } 145 | } 146 | } 147 | BS.resize(VCol.size(), BV_list.size()); 148 | BS.setFromTriplets(coefficients.begin(), coefficients.end()); 149 | } 150 | 151 | void construct_blendshape_mat(const Eigen::MatrixXd& V, 152 | const std::vector& BV_list, 153 | //Eigen::RowVectorXd Vcenter, double Vbound, 154 | Eigen::MatrixXd& BS) 155 | { 156 | Eigen::MatrixXd VT = V.transpose(); 157 | Eigen::VectorXd VCol(Eigen::Map(VT.data(), V.cols()*V.rows())); 158 | 159 | BS.resize(VCol.size(), BV_list.size()); 160 | BS.setZero(); 161 | for(int j=0; j(BVT.data(), BV.cols()*BV.rows()); 169 | 170 | Eigen::VectorXd deltaV = bVcol-VCol; 171 | for(int i=0; i1e-12){ 173 | BS(i,j)=deltaV(i); 174 | //} 175 | } 176 | } 177 | } 178 | 179 | void read_blendshape_data( 180 | std::string bs_list_file, std::string bs_folder, std::string animfile, 181 | const Eigen::MatrixXd& TV, 182 | //Eigen::SparseMatrix& BS, 183 | Eigen::MatrixXd& BS, 184 | std::vector& T_list 185 | ) 186 | { 187 | 188 | std::vector mesh_name_list; 189 | read_mesh_files_from_directory(bs_folder, mesh_name_list); 190 | 191 | std::vector BV_list; 192 | read_blendshape_list(bs_folder, bs_list_file, mesh_name_list, BV_list); 193 | read_blendshape_anim(animfile, T_list); 194 | 195 | //Eigen::SparseMatrix BS; 196 | //construct_blendshape_mat(TV, BV_list, Vcenter, Vbound, BS); 197 | construct_blendshape_mat(TV, BV_list, BS); 198 | } 199 | 200 | void mexFunction( 201 | int nlhs, 202 | mxArray *plhs[], 203 | int nrhs, 204 | const mxArray *prhs[]) 205 | { 206 | Eigen::MatrixXd TV; 207 | 208 | char* bs_list_file = mxArrayToString(prhs[0]); 209 | char* bs_folder = mxArrayToString(prhs[1]); 210 | char* animfile = mxArrayToString(prhs[2]); 211 | igl::matlab::parse_rhs_double(prhs+3,TV); 212 | //Eigen::SparseMatrix BS; 213 | Eigen::MatrixXd BS; 214 | std::vector T_list; 215 | 216 | 217 | read_blendshape_data(bs_list_file, bs_folder, animfile, TV, BS, T_list); 218 | 219 | igl::matlab::prepare_lhs_double(BS, plhs); 220 | 221 | plhs[1] = mxCreateCellMatrix(T_list.size(),1); 222 | 223 | mxArray *x; 224 | for(int i=0; i > map(mxGetPr(x),m,n); 229 | map = T_list[i].template cast(); 230 | mxSetCell(plhs[1], i, x); 231 | } 232 | return; 233 | } 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /matlab-include/mex/read_blendshape_anim.mexmaci64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/matlab-include/mex/read_blendshape_anim.mexmaci64 -------------------------------------------------------------------------------- /matlab-include/utils/build_selection_matrix.m: -------------------------------------------------------------------------------- 1 | % xy xy xy 2 | 3 | % S is sparse 4 | function S = build_selection_matrix(Uc,Bd_idx) 5 | Bd_idx = reshape(Bd_idx,size(Bd_idx,1)*size(Bd_idx,2),1); 6 | I = zeros(size(Bd_idx)); 7 | J = zeros(size(Bd_idx)); 8 | V = zeros(size(Bd_idx)); 9 | for i = 1:size(Bd_idx,1) 10 | I(i) = i; 11 | J(i) = Bd_idx(i); 12 | V(i) = 1; 13 | end 14 | S = sparse(I,J,V,size(Bd_idx,1),size(Uc,1)); 15 | end -------------------------------------------------------------------------------- /matlab-include/utils/catmull_rom_handle.m: -------------------------------------------------------------------------------- 1 | function [X,Y,tX,tY,nX,nY] = catmull_rom_handle(handleX,handleY,num) 2 | 3 | assert(size(handleX,2) > 1 || size(handleX,1) > 1); 4 | handleX = reshape(handleX,1,size(handleX,1)*size(handleX,2)); 5 | handleY = reshape(handleY,1,size(handleY,1)*size(handleY,2)); 6 | 7 | T = linspace(0,1,(size(handleX,2)-1)*num+1); 8 | handleT = T(1:num:end); 9 | X = zeros(size(T)); 10 | Y = zeros(size(T)); 11 | tX = zeros(size(T)); 12 | tY = zeros(size(T)); 13 | nX = zeros(size(T)); 14 | nY = zeros(size(T)); 15 | 16 | for i = 1:(size(T,2)-1) 17 | idx0 = ceil(i/num); 18 | idx1 = ceil(i/num)+1; 19 | t0 = handleT(idx0); 20 | t1 = handleT(idx1); 21 | t = T(i); 22 | t = (t-t0)/(t1-t0); 23 | if idx0 == 1 && idx1 == size(handleT,2) 24 | mX0 = (handleX(idx0+1)-handleX(idx0))/(handleT(idx0+1)-handleT(idx0)); 25 | mX1 = (handleX(idx1)-handleX(idx1-1))/(handleT(idx1)-handleT(idx1-1)); 26 | mY0 = (handleY(idx0+1)-handleY(idx0))/(handleT(idx0+1)-handleT(idx0)); 27 | mY1 = (handleY(idx1)-handleY(idx1-1))/(handleT(idx1)-handleT(idx1-1)); 28 | elseif idx0 == 1 && idx1 ~= size(handleT,2) 29 | mX0 = (handleX(idx0+1)-handleX(idx0))/(handleT(idx0+1)-handleT(idx0)); 30 | mX1 = (handleX(idx1+1)-handleX(idx1-1))/(handleT(idx1+1)-handleT(idx1-1)); 31 | mY0 = (handleY(idx0+1)-handleY(idx0))/(handleT(idx0+1)-handleT(idx0)); 32 | mY1 = (handleY(idx1+1)-handleY(idx1-1))/(handleT(idx1+1)-handleT(idx1-1)); 33 | elseif idx0 ~= 1 && idx1 == size(handleT,2) 34 | mX0 = (handleX(idx0+1)-handleX(idx0-1))/(handleT(idx0+1)-handleT(idx0-1)); 35 | mX1 = (handleX(idx1)-handleX(idx1-1))/(handleT(idx1)-handleT(idx1-1)); 36 | mY0 = (handleY(idx0+1)-handleY(idx0-1))/(handleT(idx0+1)-handleT(idx0-1)); 37 | mY1 = (handleY(idx1)-handleY(idx1-1))/(handleT(idx1)-handleT(idx1-1)); 38 | else 39 | mX0 = (handleX(idx0+1)-handleX(idx0-1))/(handleT(idx0+1)-handleT(idx0-1)); 40 | mX1 = (handleX(idx1+1)-handleX(idx1-1))/(handleT(idx1+1)-handleT(idx1-1)); 41 | mY0 = (handleY(idx0+1)-handleY(idx0-1))/(handleT(idx0+1)-handleT(idx0-1)); 42 | mY1 = (handleY(idx1+1)-handleY(idx1-1))/(handleT(idx1+1)-handleT(idx1-1)); 43 | end 44 | pX0 = handleX(idx0); 45 | pX1 = handleX(idx1); 46 | pY0 = handleY(idx0); 47 | pY1 = handleY(idx1); 48 | pX = (2*t^3-3*t^2+1)*pX0 + (t^3 - 2*t^2 + t)*(handleT(idx1)-handleT(idx0))*mX0 + (-2*t^3+3*t^2)*pX1 + (t^3 -t^2)*(handleT(idx1)-handleT(idx0))*mX1; 49 | pY = (2*t^3-3*t^2+1)*pY0 + (t^3 - 2*t^2 + t)*(handleT(idx1)-handleT(idx0))*mY0 + (-2*t^3+3*t^2)*pY1 + (t^3 -t^2)*(handleT(idx1)-handleT(idx0))*mY1; 50 | ptX = (6*t^2-6*t)*pX0 + (3*t^2 - 4*t + 1)*(handleT(idx1)-handleT(idx0))*mX0 + (-6*t^2+6*t)*pX1 + (3*t^2 -2*t)*(handleT(idx1)-handleT(idx0))*mX1; 51 | ptY = (6*t^2-6*t)*pY0 + (3*t^2 - 4*t + 1)*(handleT(idx1)-handleT(idx0))*mY0 + (-6*t^2+6*t)*pY1 + (3*t^2 -2*t)*(handleT(idx1)-handleT(idx0))*mY1; 52 | N = [0 -1; 1 0]*[ptX;ptY]; 53 | X(i) = pX; 54 | Y(i) = pY; 55 | tX(i) = ptX/norm([ptX ptY]); 56 | tY(i) = ptY/norm([ptX ptY]); 57 | nX(i) = N(1)/norm(N); 58 | nY(i) = N(2)/norm(N); 59 | end 60 | 61 | % last handle 62 | X(end) = handleX(end); 63 | Y(end) = handleY(end); 64 | tX(end) = mX1/norm([mX1 mY1]); 65 | tY(end) = mY1/norm([mX1 mY1]); 66 | Nend = [0 -1; 1 0]*[mX1;mY1]; 67 | nX(end) = Nend(1)/norm(Nend); 68 | nY(end) = Nend(2)/norm(Nend); 69 | 70 | % columnwise 71 | X = X'; 72 | Y = Y'; 73 | tX = tX'; 74 | tY = tY'; 75 | nX = nX'; 76 | nY = nY'; 77 | end -------------------------------------------------------------------------------- /matlab-include/utils/cluster_pnts_to_closest.m: -------------------------------------------------------------------------------- 1 | % V vertex postions 2 | % C cluster postions 3 | % I indices of each vertex's closest cluster 4 | 5 | function [I] = cluster_pnts_to_closest(V,C) 6 | I = zeros(size(V,1),1); 7 | for i = 1:size(V,1) 8 | v = V(i,:); 9 | % euclidean distance 10 | D = sum((C-v).^2,2); 11 | idx = find(D == min(D)); 12 | I(i) = idx(1); 13 | end 14 | end -------------------------------------------------------------------------------- /matlab-include/utils/default_D_matrix.m: -------------------------------------------------------------------------------- 1 | % phi default fudge factor to use 2 | % Em indices of the points that are controlled by the orthogonality 3 | % constraint 4 | function [phi,Em] = default_D_matrix(V,T) 5 | 6 | dim = size(V,2); 7 | 8 | if dim == 2 9 | 10 | L = cotmatrix(V,T); 11 | Mr = massmatrix(V,T); 12 | Q = -L; 13 | l = Mr * ones(size(V,1),1); 14 | [phi_e,~] = min_quad_with_fixed(Q,l,unique(outline(T)),zeros(size(unique(outline(T)),1),1),[],[],[]); 15 | phi = zeros(size(V,1)*size(V,2)); 16 | for i = 1:size(phi_e) 17 | phi(2*i,2*i) = phi_e(i); 18 | phi(2*i-1,2*i-1) = phi_e(i); 19 | end 20 | phi = sparse(phi); 21 | Em = find(phi_e ~= 0); 22 | 23 | elseif dim == 3 24 | 25 | F = boundary_faces(T); 26 | L = cotmatrix(V,T); 27 | Mr = massmatrix(V,T); 28 | Q = -L; 29 | l = Mr * ones(size(V,1),1); 30 | [phi_e,~] = min_quad_with_fixed(Q,l,unique(F),zeros(size(unique(F),1),1),[],[],[]); 31 | 32 | % phi = zeros(size(V,1)*size(V,2)); 33 | % for i = 1:size(phi_e) 34 | % phi(3*i,3*i) = phi_e(i); 35 | % phi(3*i-1,3*i-1) = phi_e(i); 36 | % phi(3*i-2,3*i-2) = phi_e(i); 37 | % end 38 | % phi = sparse(phi); 39 | % Em = find(phi_e ~= 0); 40 | 41 | phiI = [3*(1:size(phi_e,1))';3*(1:size(phi_e,1))'-1;3*(1:size(phi_e,1))'-2]; 42 | phiJ = phiI; 43 | phiV = repmat(phi_e,3,1); 44 | phi = sparse(phiI,phiJ,phiV); 45 | Em = find(phi_e ~= 0); 46 | 47 | end 48 | 49 | end -------------------------------------------------------------------------------- /matlab-include/utils/edge_selection_matrix.m: -------------------------------------------------------------------------------- 1 | % xxx yyy 2 | 3 | % S is sparse 4 | function S = edge_selection_matrix(V,E) 5 | 6 | dim = size(V,2); 7 | 8 | if dim == 2 9 | num_edges = size(E,1); 10 | num_vertices = size(V,1); 11 | 12 | % each edge introduces 4 entries to S 13 | I = zeros(2*2*num_edges,1); 14 | J = zeros(2*2*num_edges,1); 15 | Va = zeros(2*2*num_edges,1); 16 | 17 | for i = 1:num_edges 18 | 19 | I(4*(i-1)+1) = i; 20 | I(4*(i-1)+2) = i; 21 | I(4*(i-1)+3) = i+num_edges; 22 | I(4*(i-1)+4) = i+num_edges; 23 | 24 | J(4*(i-1)+1) = E(i,1); 25 | J(4*(i-1)+2) = E(i,2); 26 | J(4*(i-1)+3) = E(i,1)+num_vertices; 27 | J(4*(i-1)+4) = E(i,2)+num_vertices; 28 | 29 | Va(4*(i-1)+1) = 1; 30 | Va(4*(i-1)+2) = -1; 31 | Va(4*(i-1)+3) = 1; 32 | Va(4*(i-1)+4) = -1; 33 | 34 | end 35 | S = sparse(I,J,Va,2*num_edges,2*num_vertices); 36 | 37 | elseif dim == 3 38 | 39 | num_edges = size(E,1); 40 | num_vertices = size(V,1); 41 | 42 | % each edge introduces 6 entries to S 43 | I = zeros(3*2*num_edges,1); 44 | J = zeros(3*2*num_edges,1); 45 | Va = zeros(3*2*num_edges,1); 46 | 47 | for i = 1:num_edges 48 | 49 | I(6*(i-1)+1) = i; 50 | I(6*(i-1)+2) = i; 51 | I(6*(i-1)+3) = i+num_edges; 52 | I(6*(i-1)+4) = i+num_edges; 53 | I(6*(i-1)+5) = i+num_edges*2; 54 | I(6*(i-1)+6) = i+num_edges*2; 55 | 56 | J(6*(i-1)+1) = E(i,1); 57 | J(6*(i-1)+2) = E(i,2); 58 | J(6*(i-1)+3) = E(i,1)+num_vertices; 59 | J(6*(i-1)+4) = E(i,2)+num_vertices; 60 | J(6*(i-1)+5) = E(i,1)+num_vertices*2; 61 | J(6*(i-1)+6) = E(i,2)+num_vertices*2; 62 | 63 | Va(6*(i-1)+1) = 1; 64 | Va(6*(i-1)+2) = -1; 65 | Va(6*(i-1)+3) = 1; 66 | Va(6*(i-1)+4) = -1; 67 | Va(6*(i-1)+5) = 1; 68 | Va(6*(i-1)+6) = -1; 69 | 70 | end 71 | 72 | S = sparse(I,J,Va,3*num_edges,3*num_vertices); 73 | 74 | 75 | end 76 | 77 | end -------------------------------------------------------------------------------- /matlab-include/utils/lbs_matrix_xyz.m: -------------------------------------------------------------------------------- 1 | function [M] = lbs_matrix_xyz(V,W) 2 | 3 | n = size(V,1); % num of vertices 4 | m = size(W,2); % num of handles 5 | dim = size(V,2); 6 | 7 | rows = zeros(dim*(dim+1)*m*n,1); 8 | cols = zeros(dim*(dim+1)*m*n,1); 9 | vals = zeros(dim*(dim+1)*m*n,1); 10 | 11 | cur = 1; 12 | 13 | for x = 1:dim 14 | for j = 1:n 15 | for i = 1:m 16 | for c = 1:(dim+1) 17 | value = W(j,i); 18 | if c ~= (dim+1) 19 | value = value*V(j,c); 20 | end 21 | % % xxx yyy zzz 22 | % rows(cur) = (x-1)*n + j; 23 | % cols(cur) = (x-1)*m + (c-1)*m*dim + i; 24 | % vals(cur) = value; 25 | 26 | % xyz xyz 27 | rows(cur) = dim*(j-1)+x; 28 | cols(cur) = (x-1)*m + (c-1)*m*dim + i; 29 | vals(cur) = value; 30 | 31 | cur = cur + 1; 32 | end 33 | end 34 | end 35 | end 36 | 37 | M = sparse(rows,cols,vals,n*dim,m*dim*(dim+1)); 38 | 39 | end -------------------------------------------------------------------------------- /matlab-include/utils/mass_spring.m: -------------------------------------------------------------------------------- 1 | function [G,H] = mass_spring(V,E,k,U) 2 | assert(size(E,2) == 2); 3 | U = reshape(U,size(V)); 4 | 5 | % rest edge lengths 6 | LV = edge_lengths(V,E); 7 | LU = edge_lengths(U,E); 8 | f = k*0.5*sum((LV-LU).^2); 9 | 10 | if nargout==0 11 | return; 12 | end 13 | 14 | I = E(:,2); 15 | J = E(:,1); 16 | T0 = U(I,:) - U(J,:); 17 | t1 = normrow(T0); 18 | 19 | GI = ((t1-LV)./t1).*T0; 20 | GJ = -GI; 21 | 22 | dim = size(V,2); 23 | G = k*full(sparse([repmat(I,1,dim) repmat(J,1,dim)],repmat(1:dim,size(E,1),2),[GI GJ],size(V,1),dim)); 24 | G = G(:); % to match the dimension: not sure if correct 25 | 26 | if nargout==1 27 | return; 28 | end 29 | 30 | % Outer product 31 | vec = @(X) X(:); 32 | T2 = T0(:,vec(repmat(1:dim,dim,1))').*T0(:,vec(repmat(1:dim,1,dim))'); 33 | t3 = t1 - LV; 34 | 35 | HIJ = (t3./(t1.^3) - 1./(t1.^2)).*T2 - t3./t1.*(vec(eye(dim))'); 36 | HII = -HIJ; 37 | HJJ = -HIJ; 38 | HJI = HIJ; 39 | n = size(V,1); 40 | H = sparse(n*dim,n*dim); 41 | for ii = 1:dim 42 | for jj = 1:dim 43 | oi = (ii-1)*dim+jj; 44 | Hiijj = sparse( ... 45 | [I I J J],[I J I J],[HII(:,oi) HIJ(:,oi) HJI(:,oi) HJJ(:,oi)],n,n); 46 | H(((ii-1)*n)+(1:n),((jj-1)*n)+(1:n)) = Hiijj; 47 | end 48 | end 49 | H = k*H; 50 | 51 | end 52 | -------------------------------------------------------------------------------- /matlab-include/utils/massmatrix_xyz.m: -------------------------------------------------------------------------------- 1 | function Mxyz = massmatrix_xyz(V,F) 2 | M = massmatrix(V,F); 3 | Meles = diag(M); 4 | % 2D 5 | if size(V,2) == 2 6 | M2eles = zeros(2*size(M,1),1); 7 | M2eles(2*(1:size(M,1))) = Meles; 8 | M2eles(2*(1:size(M,1))-1) = Meles; 9 | Mxyz = sparse(1:2*size(M,1),1:2*size(M,1),M2eles,2*size(M,1),2*size(M,1)); 10 | % 3D 11 | elseif size(V,2) == 3 12 | M3eles = zeros(3*size(M,1),1); 13 | M3eles(3*(1:size(M,1))) = Meles; 14 | M3eles(3*(1:size(M,1))-1) = Meles; 15 | M3eles(3*(1:size(M,1))-2) = Meles; 16 | Mxyz = sparse(1:3*size(M,1),1:3*size(M,1),M3eles,3*size(M,1),3*size(M,1)); 17 | end 18 | end -------------------------------------------------------------------------------- /matlab-include/utils/newton_line_search.m: -------------------------------------------------------------------------------- 1 | function [alpha] = newton_line_search(f,tmp_g,dUc,Ur,Uc) 2 | alpha = 1; 3 | p = 0.5; 4 | c = 1e-8; 5 | 6 | % perform backtracking line search 7 | f0 = f(Ur,Uc); 8 | s = f0 + c * tmp_g' * dUc; % to ensure sufficient decrease 9 | 10 | while alpha > c 11 | Uc_tmp = Uc + alpha * dUc; 12 | if f(Ur,Uc_tmp) <= s 13 | break; 14 | end 15 | alpha = alpha * p; 16 | end 17 | 18 | end -------------------------------------------------------------------------------- /matlab-include/utils/read_2d_bone_anim.m: -------------------------------------------------------------------------------- 1 | function [T_list] = read_2d_bone_anim(filename,C,BE) 2 | 3 | fileID=fopen(filename,'r'); 4 | nf=fscanf(fileID,'%d',1); 5 | m=fscanf(fileID,'%d',1); 6 | TM=fscanf(fileID,'%f', [3*m nf+1]); 7 | fclose(fileID); 8 | TM = TM'; 9 | 10 | P = bone_parents(BE); 11 | 12 | d2r = pi/180; 13 | 14 | T_list = cell(nf,1); 15 | 16 | 17 | Tlr = zeros(m,2); 18 | for b=1:m 19 | Tlr(b,:) = TM(1,3*(b-1)+1:3*(b-1)+2); 20 | end 21 | 22 | function fk2d(b) 23 | if ~computed(b) 24 | p = P(b); 25 | if p < 1 26 | theta = TMi(:,3*(b-1)+3); 27 | %theta = TMi(b); 28 | Ti(3*(b-1)+1:3*b,:) = transform2d(theta*d2r,C(BE(b,1),1),C(BE(b,1),2)); 29 | else 30 | fk2d(p); 31 | theta = TMi(:,3*(b-1)+3); 32 | %theta = TMi(b); 33 | Ti(3*(b-1)+1:3*b,:) = Ti(3*(p-1)+1:3*p,:)*transform2d(theta*d2r,C(BE(b,1),1),C(BE(b,1),2)); 34 | end 35 | computed(b) = true; 36 | end 37 | end 38 | 39 | 40 | for ai=1:nf 41 | computed = false(m,1); 42 | TMi = TM(ai+1,:); 43 | Ti = zeros(3*m,3); 44 | for b =1:m 45 | fk2d(b); 46 | end 47 | T = zeros(2,3,m); 48 | for b =1:m 49 | if(P(b)<1) 50 | Tl = TM(ai+1,3*(b-1)+1:3*(b-1)+2)-Tlr(b,:); 51 | Ti(3*(b-1)+1:3*(b-1)+2,3) = Ti(3*(b-1)+1:3*(b-1)+2,3) + Tl'; 52 | end 53 | T(:,:,b) = Ti(3*(b-1)+1:3*(b-1)+2,:); 54 | end 55 | T_list{ai,1} = reshape(permute(T,[3 1 2]),m*6,1); 56 | end 57 | 58 | end 59 | 60 | -------------------------------------------------------------------------------- /matlab-include/utils/read_2d_pnt_anim.m: -------------------------------------------------------------------------------- 1 | function [T_list] = read_2d_pnt_anim(filename,C,PI) 2 | 3 | 4 | %TM = readMatrix(filename); 5 | 6 | fileID=fopen(filename,'r'); 7 | nf=fscanf(fileID,'%d',1); 8 | m=fscanf(fileID,'%d',1); 9 | TM=fscanf(fileID,'%f', [3*m nf+1]); 10 | fclose(fileID); 11 | TM = TM'; 12 | 13 | d2r = pi/180; 14 | 15 | T_list = cell(nf,1); 16 | 17 | 18 | Tlr = zeros(m,2); 19 | for b=1:m 20 | Tlr(b,:) = TM(1,3*(b-1)+1:3*(b-1)+2); 21 | end 22 | 23 | 24 | for ai=1:nf 25 | T = zeros(2,3,m); 26 | for b =1:m 27 | Tl = TM(ai+1,3*(b-1)+1:3*(b-1)+2)-Tlr(b,:); 28 | theta = TM(ai+1,3*(b-1)+3); 29 | TR = transform2d(theta*d2r,C(PI(b),1),C(PI(b),2)); 30 | TR(1:2,3) = TR(1:2,3) + Tl'; 31 | T(:,:,b) = TR(1:2,:); 32 | end 33 | T_list{ai,1} = reshape(permute(T,[3 1 2]),m*6,1); 34 | end 35 | 36 | end 37 | 38 | -------------------------------------------------------------------------------- /matlab-include/utils/save_bbw_bone.m: -------------------------------------------------------------------------------- 1 | function [W]=save_bbw_bone(filename, V,F,C,P,BE) 2 | 3 | [NV,NF] = remesh_at_handles(V,F,C,P,BE,[]); 4 | [b,bc] = boundary_conditions(NV,NF,C,P,BE); 5 | W = biharmonic_bounded(NV,NF,b,bc,'OptType','quad'); 6 | I=snap_points(V,NV); 7 | W=W(I,:); 8 | W = W./repmat(sum(W,2),1,size(W,2)); 9 | writeDMAT(filename, W); 10 | 11 | end -------------------------------------------------------------------------------- /matlab-include/utils/save_bbw_pnt.m: -------------------------------------------------------------------------------- 1 | function [W]=save_bbw_pnt(filename, V,F,C) 2 | 3 | [NF] = remesh_at_points(V,F,C); 4 | NV = [V;C]; 5 | [b,bc] = boundary_conditions(NV,NF,C); 6 | W = biharmonic_bounded(NV,NF,b,bc,'OptType','quad'); 7 | I=snap_points(V,NV); 8 | W=W(I,:); 9 | W = W./repmat(sum(W,2),1,size(W,2)); 10 | writeDMAT(filename, W); 11 | 12 | end -------------------------------------------------------------------------------- /matlab-include/utils/set_project_path.m: -------------------------------------------------------------------------------- 1 | function set_project_path() 2 | 3 | addpath('../../matlab-include/utils'); 4 | addpath('../../matlab-include/mex'); 5 | addpath(genpath('../../gptoolbox')); 6 | addpath(genpath('../../Bartels/matlab')); 7 | 8 | end 9 | -------------------------------------------------------------------------------- /matlab-include/utils/transform2d.m: -------------------------------------------------------------------------------- 1 | function R = transform2d(theta,x,y) 2 | R=zeros(3,3); 3 | cost = cos(theta); 4 | sint = sin(theta); 5 | R(1,1) = cost; 6 | R(1,2) = -sint; 7 | R(2,1) = sint; 8 | R(2,2) = cost; 9 | R(1,3) = -x*cost+y*sint+x; 10 | R(2,3) = -x*sint-y*cost+y; 11 | R(3,3) = 1; 12 | end -------------------------------------------------------------------------------- /matlab-include/utils/wire_deform.m: -------------------------------------------------------------------------------- 1 | % V vertex positions 2 | % I indices of each vertex's closest cluster 3 | % new_C new Catmull handles 4 | % sample_num number of samples for Catmull interpolation 5 | % Vr deformed positions by wire deformer 6 | % X Y updated cluster positions 7 | 8 | function [Vr,X,Y] = wire_deform(V,I,new_C,sample_num,X0,Y0,tX0,tY0,nX0,nY0) 9 | [X,Y,tX,tY,nX,nY] = catmull_rom_handle(new_C(:,1),new_C(:,2),sample_num); 10 | Vr = zeros(size(V)); 11 | % update position 12 | for i = 1:size(V,1) 13 | v = V(i,:); 14 | idx = I(i); 15 | Vr(i,:) = [tX(idx) nX(idx); tY(idx) nY(idx)]*inv([tX0(idx) nX0(idx); tY0(idx) nY0(idx)])*(v-[X0(idx) Y0(idx)])'+[X(idx) Y(idx)]'; 16 | end 17 | end -------------------------------------------------------------------------------- /showcases/bird_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ErisZhang/complementary-dynamics/87d11804b79d37199669645dd12ce6f00fce513c/showcases/bird_out.gif --------------------------------------------------------------------------------