流体模拟与SPH方法
流体的物理模拟与SPH方法 在引入有限元之前,先简单介绍相关的物理理论。在后面的部分,使用粗体符号如 $\boldsymbol{x}$ 表示向量或矩阵(张量), 未加粗的符号为标量, 如 $x$。
1、拉格朗日视角与欧拉视角
烟雾、海浪、水滴…,这些司空见怪的自然现象其实有着非常复杂的数学规律,对于流体等连续介质材料的研究,有两种完全不同的视角,分别是欧拉视角和拉格朗日视角。
欧拉视角的坐标系是固定的,如同站在河边观察河水的流动一样,用这种视角分析流体需要建立网格单元,使用网格将流体分成一个个小的“单元”,在这些单元上进行流体的物理模拟,计算相关的物理量等,这种思路与有限元方法联系了起来。而拉格朗日视角则将流体视为流动的单元,例如将一片羽毛放入风中,那么羽毛的轨迹可以帮我们指示空气的流动规律。
SPH算法是典型的拉格朗日视角,它的基本原理就是通过粒子模拟来流体的运动规律,然后再通过表面重建算法(Marching Cube)从粒子中生成网格来进行流体渲染。
2、SPH粒子受力分析 SPH方法将流体看作大量粒子的集合,使用粒子的 ...
弹性有限元方法
弹性有限元与超弹性物体模拟方法 在引入有限元之前,先简单介绍相关的物理理论。在后面的部分,使用粗体符号如 $\boldsymbol{x}$ 表示向量或矩阵(张量), 未加粗的符号为标量, 如 $x$。
1、形变(Deformation)当弹性材料发生形变,其上点$x$会移动到新的位置,我们形变映射(Deformation map) $\boldsymbol \phi$ 表达此关系,它是一个向量到向量的映射。有:
$$\boldsymbol x_{deformed} = \boldsymbol \phi( \boldsymbol x_{rest})$$
为了更好地描述形变,通常使用形变梯度(deformation gradient)来表示这个形变。形变梯度定义为:
$$\boldsymbol F = \frac{\partial \boldsymbol \phi( \boldsymbol x_{rest})}{\partial \boldsymbol x_{rest}} = \frac{\boldsymbol x_{deformed}}{\bold ...
弹簧质点系统与时间积分
弹簧质点系统一个模拟变形物体最简单的方法就是将其表示为弹簧质点系统(Mass Spring Systems)。一个弹簧质点包含了一系列由多个弹簧连接起来的质点,这样的系统的物理属性非常直接,模拟程序也很容易编写。
虽然模型简单,但是也带来了一些问题:
1.物体的行为依赖于弹簧系统的设置方法;
2.很难通过调整弹簧系数来得到想要的结果;
3.弹簧质点网格不能直接获取体效果。
在很多的应用中这些缺点可以忽略,在这种场合下,弹簧质点网格是最好的选择,因为够快够简单。弹簧质点系统可用于模拟绳索、布料、头发等弹性物体。
力是改变物体运动状态的原因,在这个系统中,主要有两种力,一是弹簧的弹力和阻尼力。
对于连接两个质点的一个弹簧,弹力是:
阻尼力可以这样算:
假设系统中有N个质点,质量为$m_i$,位置为$x_i$,速度为$v_i$ , $1 < i < N$.
这些质点由一组弹簧S连接,弹簧参数为($i$, $j$, $l_0$, $k_s$, $k_d$)。$i$,$j$为连接的弹簧质点,$l_0$为弹簧完全放松时的长度,$k_s$为弹簧弹性系数,$k_d$为阻尼系数,由胡科定律知 ...
OpenGL坐标系统
OpenGL坐标系统引用 | Coordinate Systems
在计算机图形学中,利用矩阵的变换来实现物体在各个坐标系中的坐标变换,进而呈现出期望的效果。OpenGL希望在每次顶点着色器运行后,可见的所有顶点都为标准化设备坐标(Normalized Device Coordinate, NDC)。也就是说,每个顶点的x,y,z坐标都应该在 -1.0到1.0 之间,超出这个坐标范围的顶点都将不可见。我们通常会自己设定一个坐标的范围,之后再在顶点着色器中将这些坐标变换为标准化设备坐标。然后将这些标准化设备坐标传入光栅器(Rasterizer),将它们变换为屏幕上的二维坐标或像素。
将坐标变换为标准化设备坐标,接着再转化为屏幕坐标的过程通常是分步进行的,也就是类似于流水线那样子。在流水线中,物体的顶点在最终转化为屏幕坐标之前还会被变换到多个坐标系统(Coordinate System)。将物体的坐标变换到几个过渡坐标系(Intermediate Coordinate System)的优点在于,在这些特定的坐标系统中,一些操作或运算更加方便和容易。图形学中比较重要的总共有5个不同的 ...
Doxygen自动生成文档
Doxygen 生成文档1.简介 我们在编写代码时一般会写一些注释,在写文档时又会用到这些注释。如果不能直接利用这些注释,就会做很多重复的工作。因此,Doxygen立足于解决这个问题,只要我们在写注释时按一定的格式来写,它就可以将我们在写代码时写的注释转化为各种格式的文档,已支持包括 HTML, LATEX, MAN pages, REF doc, XML, Docbook等多种格式。
很多项目都使用了Doxygen来生成文档。比如:LLVM, CGAL, VTK,glm,Eigen等。
Doxygen生成的流程概述如下:
1.Doxygen
Doxygen能将程序中的特定批注转换成为说明文件。它可以依据程序本身的结构,将程序中按规范注释的批注经过处理生成一个纯粹的参考手册,通过提取代码结构或借助自动生成的包含依赖图(include dependency graphs)、继承图(inheritance diagram)以及协作图(collaboration diagram)来可视化文档之间的关系。它支持多种语言,包括C, C++, pyth ...
CMAKE入门
What CMake can do跨平台构建 一套C/C++代码,多平台运行。假设在Windows上, OSX和Linux上使用:Visual Studio, Xcode, Makefile.可以一套代码基于同一个CMAKE即时编译。直接生成项目,不需要额外配置。
VCS友好 当项目出现更新,如添加一个新文件。这个工作如果交给IDE来做,很麻烦。交给CMAKE,只需要一行代码,类似于Makefile做的。
多生成环境支持 CMAKE已经开始支持多种IDE工具,可以直接通过CMAKE生成IED对应的项目,当切换IDE进行开发时,只需要简单一步即可构建。可直接生成VS项目、xcode项目,eclipse项目、各种平台的Makefile等。
CMAKE现已支持如下的IDE及开发环境。可通过
cmake -help
来查看。
全流程支持 从开发到调试,从生成到构建,从编译到测试,从打包到安装全流程覆盖。
HOW TO LEARN CMAKE 官方文档
Microsoft
github ...
C++参数传递方式及区别
一、C++参数传递方式 C++自C语言发展而来,继承了C语言中的函数及按值传递和按指针传递的参数传递方式。但是出于效率与安全的综合考虑,C++引入了引用这个语言特性。而引用被设计主要就是为了作为函数参数,这使得函数运行时的变量成为调用时变量的一个别名。这种参数传递的方式成为引用传递。按引用传递允许被调用的函数能够访问调用函数中的变量。
这种参数传递的方式与值传递不同,后者传递的是函数被调用时的变量的值的拷贝;引用传递与指针传递有些类似,但是又不完全相同。
1、值传递 传递的是调用函数时传入变量的一个拷贝。比如一个int数,一个结构体的拷贝。在函数内部对应的变量与调用时传入的变量是两个个体,前者是后者的拷贝。这也就是说,无论在函数内部如何修改按值传递的变量,函数返回时原先的变量不会受到修改。
按值传递的参数传递方式有两个主要的问题:(1)实际传入的参数是调用时参数的拷贝。同样的内容占两份内存,如果变量是基本数据类型那不会占用太大的空间,如果是占用大空间的变量,比如结构体,类对象等,就会造成空间浪费。(2)函数调用返回后对于调用时的参数没有更改, ...
C++中的指针与引用
C/C++中的指针是一个既让人喜欢又恨的特性。使用指针,既方便了代码的编写,但是随之而来的就是各种因空指针、野指针导致的问题。随着语言的发展,C++中出现了引用这个C语言中所没有的特性。因为引用与指针的 “貌合神离” 使得许多人对指针与引用的正确使用一头雾水,摸不着头脑。
一、指针与引用1、指针 指针,是一个特殊的变量,与int、float之类的变量一样存储变量的值。只是这个值比较特殊:它是另一个变量的地址。对于一个不受限定的指针(非const,非volatile),C++支持通过对指针变量的操作来间接访问和修改它存储的地址的值。因为他是一个变量,所以它存在地址空间,也可以通过修改它存储的地址值来让它指向另一个对象。
对于一个不受限的指针,由于允许它不存储任何变量的地址(空指针)。而且支持多级指针。复杂的语义使得往往在使用时出现各种问题,尤其是在指针作为函数的参数和返回值的时候。出于对于安全和效率的考虑,C++出现了引用这个语言特性。
2、引用 简单来说,引用是已定义变量的别名。就如同一个人有几个名字一样,一个大名几个外号一样,无论 ...
GCC自带的一些builtin内建函数
一、GCC内建函数 最近在刷 leetcode 的时候遇到了一些以__builtin开头的函数,它们被用在状态压缩相关的题目中特别有用,于是就去了解了一下。
原来这些函数是GCC编译器自带的内建函数。这些__builtin_*形式的内建函数一般是基于不同硬件平台采用专门的硬件指令实现的,因此性能较高。在刷题时可以直接用而不用重复造轮子,尤其是一些涉及到位操作的内建函数真的特别有用。
我对其中涉及到位运算的内建函数挺感兴趣的,于是就去查了一下它们的接口以及具体实现。下一节主要介绍一下几个特别有用的函数。
关于GCC内建函数的更完整的内容可以参见 官方文档。
二、常用的内建函数及实现 针对实现,只实现64位无符号整型的版本。其余的版本依此类推。
1、__builtin_ctz 一共有三个函数,分别适用于不同的输入类型。
int __builtin_ctz (unsigned int x)Returns the number of trailing 0-bits in x, starting at the least sign ...
C++中const变量的修改与赋值
出于避免对数据的无意修改的需求,C及C++语言引入了const关键字。与C语言中的const相比,C++中的const具有更丰富的用法。C++中的const除了可用于修饰变量,指针,函数及函数参数,还可用于修饰类对象,类成员,类成员函数等。由于其丰富的用途,往往容易对其产生误解,尤其是与指针用法结合在一起时。下面以一些实例来说明这个问题。
一、const修饰变量1、含义 当使用const修饰普通变量时。如
int const age = 39;//或const int age = 39;
表示const关键字修饰的这个变量是一个常量,不能对其值进行修改。但实际上这句话不是绝对的。根据C++标准,对于修改const变量,属于未定义行为(指行为不可预测的计算机代码),这样一来这个行为的结果取决于各种编译器的具体实现(即不同编译器可能表现不同)。
2、修改const变量 下面来说一下如何修改const修饰的变量。可以使用直接赋值和使用指针来修改其值。如:
const int age = 39;//1.直接赋值age = 40;//2.使用指针修改i ...