• 基于网格的波动方程模拟(Wave equation on mesh)附源码


      波动方程是偏微分方程 (PDE) 里的经典方程,它在物理学中有大量应用并经常用来解释空间中的能量传播。波动方程是一个依赖时间的方程,它解释了系统状态是如何随着时间的推移而发生变化。在下面模拟波动方程时会使用会到拉普拉斯(Laplacian)算子,这是一个线性算子,具体形式在“网格形变算法”中有所解释。

      波动方程:

    其中:b为衰减系数,1/sqrt(a)为波传播速度,h为沿网格顶点法向移动的距离。

      将波动方程离散化并整理后得到:

    其中:dt为时间间隔,I为单位矩阵,L为离散Laplacian算子,hi为待求的波高,hi-1和hi-2为前两个时刻的波高。

      因此波动方程可以根据系统前两时刻的状态求解系统的当前状态。

    效果:

    水波模拟

    function [Frame] = wave_equation(V, F)
        % vertex normal
        N = per_vertex_normals(V, F);
        
        % laplacian operator
        L = cotmatrix(V, F);
        
        % identical matrix
        nV = size(V, 1);
        I = speye(nV);
    
        % set parameters
        dt = 0.0075;
        a = 200;
        b = 0.5;
        A = (1 + b*dt)*I - a*dt^2*L;
    
        % figure
        figure('Position', [400, 400, 400, 320]);
        fh = trisurf(F, V(:,1), V(:,2), V(:,3), ...
            'FaceColor', 'interp', 'FaceLighting', 'phong', ...
            'EdgeColor', 'none', 'CData', zeros(nV,1));
        view(2)
        axis equal
        axis off
        camlight
    
        set(gca, 'position', [0 0 1 1]);
        set(fh, 'ButtonDownFcn', @ondown);
    
        V0 = V;
        H = zeros(nV, 1);
        H_1 = zeros(nV, 1);
        draw_t = 0;
        i = 1;
        tic;
        while true
            H_2 = H_1;
            H_1 = H;
    
            B = (2 + b*dt)*H_1 - H_2;
            H = AB;
    
            % updata figure
            draw_t = draw_t + toc;
            if draw_t > 0.033
                V = V0 + bsxfun(@times, H, N);
                set(fh, 'Vertices', V, 'CData', H);
                drawnow;
    
                Frame(i) = getframe(gcf);
                i = i + 1;
                if i > 150
                    break;
                end
                
                tic;
                draw_t = 0;
            end
        end
    
        function ondown(src, ev)
            pt = get(gca, 'CurrentPoint');
    
            dH = 1/10*sparse(knnsearch(V, pt(1,:)), 1, 1, nV, 1);
            H = H + dH;
        end
    end

    本文为原创,转载请注明出处:http://www.cnblogs.com/shushen

  • 相关阅读:
    在eclipse 中添加 Tomcat
    eclipse启动报错:code13
    基础_cup给出的内存地址
    巫师3_战斗_水中水鬼
    git checkout
    git学习
    Linux软件包管理之yum在线管理
    Vagrant入门1
    mvn java项目README.md文件范例
    深入理解yum工作原理
  • 原文地址:https://www.cnblogs.com/shushen/p/5123964.html
Copyright © 2020-2023  润新知