GAMES101(21~22节,动画和仿真)

Animation

关键帧

动画就是由每一帧的画面组成,因此需要知道每一帧中,物体的位置应该怎样变化

我们首先应通过仿真技术,计算每一帧每个粒子的路径位置,

至于这些粒子如何变为整体,如何渲染,这是下一步才应考虑的问题

物理模拟/仿真

mass spring system质点弹簧系统

基本单位为一个弹簧,两个质点

推导受力分析
a点受到b方向的力

胡克定律(Hooke's Law):ks劲度系数(取决于弹簧的材料) *  单位向量(方向)*(||b-a||  - l )原始长度(形变量)

根据力的相互作用,a点受到b方向的力,b点受到往a方向的力,又因为当前静止状态,也就是作用力 == 反作用力,b点受到往a方向的力 == a点受到b方向的力的反作用力

其实总的受力应为这样的平衡关系,ab都有弹力势能和拉力

这时当b松手,b的拉力消失,b点受力不再平衡,a对b产生的弹力势能,转换为动能,

没有其他力影响,因而总能量不变,动能势能不断相互转换,b永远不会停止

一阶导数,在物理模拟中在上方 · 点号,二阶用 ·· 表示

对于路程/时间函数 的一阶导数为速率,二阶导数为加速度

那么为了让b停止,需要加摩擦力,和b导数-.>b的速度的方向相反 ,其中kd依旧是劲度系数

但是这样会让所有运动都停止,假设ab同时被拉开,并且保持相对静止,同时向右运动,这时我为ab同时添加f摩擦力,因为根据上面的公式f和速度方向相反,也就是左方向,那么就会导致ab停止,但是ab的相对拉开的 状态没有改变

这样是不符合我们的期望,我们期望,b可以在左右弹的过程逐渐停止,可是当同时ab运动时,上述并不能让ab恢复弹簧的原长度,仅能让ab不再向右移动

中间缺了点乘的符号

那么如何让ab依旧保持向右移动,并且ab逐渐恢复弹簧的原长度呢?

负号(相反),单位向量a->b,b导数(速度) - a导数(速度),单位向量a->b

首先前两个,浮点 * 向量 = b->a得到的依旧是向量

后两个相乘,得到浮点,v向量 * 单位向量, = ||v|| costheta

  • 假设b相对a向右弹,那么b的速率>a的速率,且为正值,cos = 1,fr即取相反值向左
  • 假设b相对a向左弹,那么b的速率>a的速率,且为负值,cos = -1,fr即取相反值向右

这里为什么要乘以单位向量?

假设b相对于a圆周运动,ba速度虽然不同,但弹簧的长度没有改变,因为ab的相对弹力没有改变,不应该在内部施加摩擦力(圆周运动不应该有恢复原状的返回力,只有在ab方向上的速度改变,才应在内部施加摩擦力),

假如没有单位向量,那么获得的fr摩擦力向量就是速度的反向,考虑上述不应有摩擦力的情况,因此,当点乘单位向量b->a,会根据向量的夹角cos,当为90度,结果为0 ,即没有摩擦力

也就是第一个单位向量,保证了结果是向量,第二个单位向量,保证了正确的摩擦力结果

模拟

模拟一个布,不应该受到形变的影响,比如延对角线拉扯(通过蓝线),延某方向弯折,通过(较弱红线)

single particle simulation单粒子模拟

单粒子模拟:指对单个粒子运动轨迹的计算

假设知道初始位置,和每一刻的速度(矢量),那么它的任何新的位置很容易计算,但是我们根本不可能知道每一刻的速度

假设在速度场模拟粒子运动轨迹,速度场:在任意时刻t和位置x,都有对应的速度v(x,t)

也就是我们假设知道质点初始位置,速度,加速度,如何求运动轨迹?可以写为如下形式

dx / dt 导数(切线)= v,导数为瞬时速度

常微分方程

方程的形式有很多。代数方程是指含有未知数的等式;而微分方程,是指含有未知函数及其导数的等式。代数方程的解是常数,而微分方程的解是函数。

如果函数只有一个自变量的微分方程称为常微分方程(ordinary differential equation,ODE)
如果函数含有两个或者多个自变量的微分方程称为偏微分方程(partialdifferential equation,PDE)

此外,微分方程也可以根据阶数来分类:最高阶导数是一阶导数,则称为一阶微分方程(first-order-equation);最高阶导数是二阶导数,则称为二阶微分方程(second-order-equation)

Euler欧拉方法:

dx / dt = v这里的导数就是常微分方程,我们想要求解它,也就是根据自变量t,和获得的导数v,,想要求得每一刻t下的x位置

欧拉方法是求解常微分方程数值解的一种重要方法。它通过将微分方程离散化,将连续的函数关系转化为一系列离散的点之间的关系,从而利用迭代的方法逐步逼近微分方程的解。

就是利用最基本的速度,加速度公式:

下一帧的位置 = 上一帧的位置 + t增量 * 上一帧速度(矢量

下一帧的速度又等于 = 上一帧的速度 + t增量 * 上一帧加速度

可以看到,下一帧的计算参数都是由上一帧的值提供

这种欧拉方法有缺陷,delta需要很小的步长才可以准确,并且稳定性不高,有误差

midpoint method中点法

中点位置 = 上一帧的位置 + t增量 / 2  *上一帧速度

下一帧的位置 = 上一帧的位置 + t增量 * 中点位置的 速度

根据中点帧的速度,而非当前帧的速度,决定下一帧的位置

紫色线/中间黑色曲线 是正确的轨迹,黑色是计算的位置,对于普通的欧拉方法,起点的v方向是右上,t增量后即为a的位置,但是中点法看b点的速度,也就是接近于水平,t增量后即为c的位置

因此可以看到a点和紫色线的偏移大,而c点相对偏移较少

更工整的写出:

 下一帧的位置 = 上一帧的位置 + t增量 / 2 * 中点位置的速度(上一帧速度 + 下一帧的速度 = 中点速度(向量加法法则))

下一帧的速度又等于 = 上一帧的速度 + t增量 * 上一帧加速度

通过把等式二带入等式一,再展开,可以获得等式三

观察和普通欧拉方法区别,其实就是多了最后二次项

Adaptive step size自适应改变步长方法

根据减小步长\Deltat的思想,取t增量的中点,通过两次计算位置,获得t增量下的位置

和中点法不同,并非仅根据中点的速度,而是第一次用起点的速度,第二次采用中点速度

又和减小步长不同,它是动态调整的,只有计算结果 > 一定的阈值,才会执行改变步长计算,因此可以看到图二对于每一处的步长都是不同的 

Implicit methods隐式方法

使用的速度并非用上一帧的速度,而是下一帧的速度

可以看到计算的速度,对于最后一项,使用的都是下一帧的速度/ 加速度

可是下一帧的速度未知如何求解?比如解方程组,求根方法等

稳定性:

如何衡量稳定性?通过局部误差或者整体误差,和步长的关系衡量

局部误差是h ^ 2,整体误差是h(步长),

可以看到如果步长h越小,那么误差越小,

并且阶数越高越好,因为对于h来说,步长减小一半,误差减小一半,对于h^2,误差减小到1/4

h^2和(h/2)^2 ,结果为1/4

Runge-Kutta Families龙格库塔方法

RK4方法是一个4阶稳定性的方法

初始化:首先我们依旧知道每一刻的速度f(),以及在初始时间to下初始位置y0,

接下来根据步长h,可以获得tn时间的下一帧时间tn+1

这里更新位置,用上一帧yn位置 + 1/6h * 一系列的v值平均得到的速度(k值可以根据下面4个公式得到)

rigid body simulation刚体模拟

不会发生形变,因此可以看作单粒子运动,并且对应一个刚体来说,不仅仅有位置关系,我们还应该考虑它的朝向等,因此可以说它就是,单粒子运动的扩充

d/dt求一阶导数,对四个分量分别求导,得到右侧对应结果

位置 / 时间-》速度,朝向 / 时间-》角速度(旋转多块),速度 / 时间-》加速度

也就是说对于每个刚体,可以根据欧拉方法等,计算时间t下对应的位置,朝向,速度等

fuild simulation流体模拟        

position -based / verlet integration方法

非基于物理的…

//质点法:

假设水由许多刚体小球组成

假设水不能被压缩

所以,只要某处的密度发生了变化,就应该通过改变粒子的位置来“修正”

为了修正,我们要知道一个小球位置的变化对其周围密度的影响,即任何一个点的密度梯度(也就是导数)

修正位置的过程是一个梯度下降的过程-   这样简单的模拟最后会一直运动停不下来,我们可以人为的加入一些能量损失

//网格法

每个网格随时间应该如何变化

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值