• 制作简单的2D物理引擎(一)——动力学基础


    一切的基础

    在二维平面中,点$P$就是坐标$(x,y)$,点集就是一系列坐标的集合${P_1,P_2,...,P_n}$,不过这个集合是有序的(顺时针)。

    向量

    加减运算

    $$vec{P}pmvec{Q}=(P_xpm Q_x,P_ypm Q_y)$$

    $$vertvec{P}vert=sqrt{P_x^2+P_y^2}$$

    单位向量

    $$vec{e}=frac{vec{P}}{vertvec{P}vert}$$

    角度

    $$alpha=arctan(frac{y}{x})$$

    旋转

    $$
    left[egin{array}{c}
    x'\
    y'
    end{array} ight]=left[egin{array}{cc}
    cos(alpha) & -sin(alpha)\
    sin(alpha) & cos(alpha)
    end{array} ight]left[egin{array}{c}
    x\
    y
    end{array} ight]
    $$

    点积

    主要用来判断角度关系。

    $$vec{P}cdotvec{Q}=(P_{x}+Q_{x},P_{y}+Q_{y})$$

    叉积

    主要用来求面积。

    $$
    vec{P} imesvec{Q}=left|egin{array}{ccc}
    oldsymbol{vec{i}} & oldsymbol{vec{j}} & vec{oldsymbol{k}}\
    P_{x} & P_{y} & P_{z}\
    Q_{x} & Q_{y} & Q_{z}
    end{array} ight|
    $$

    物体的表示

    我们只实现一类物体——凸几何体。

    几何属性

    顶点集

    凸几何体固有的几何外形——$N$个顶点,所以只需要储存这些顶点即可。

    有人问:物体运动后,位置改变了怎么办?一般而言,要对原始顶点集做矩阵变换,才能得到最终位置。

    轴向量

    另外,为了便于计算,还需要储存一些向量——几何体每条边的单位向量。

    面积

    由已知的顶点集可以确定一个几何体,那如何求其面积?

    假设由原点$O$和任意两个相邻顶点$P$、$Q$组成三角形,那么这些所有三角形加起来就是几何形的面积。

    现在就是求$ riangle OPQ$的面积了。由叉乘的定义,两向量叉乘的结果的模就是其相应平行四边形的面积。

    故有$2S=(Q_x-P_x) imes(Q_y+P_y)$。

    重心

    在这里,物体的密度$ ho$是均匀的。

    设顶点数为$n$,顶点$P_1sim P_n$,故

    $$vec{P_G}=frac{1}{n}sum_{i=1}^{n}vec{P_i}$$

    物理属性

    质量、速度、位置、受力、密度、角偏、角加速度、扭矩、摩擦系数等。

    外观属性

    美观起见,给物体添加颜色。

    物体的运动

    力学令人着迷,用计算机来模拟力学就不那么容易了,万事开头难,做仿真还是要从理论学起。

    力学无非就是加速度、碰撞、摩擦等内容。不过对物体(刚体)来说,它的运动不是平动就是转动。

    平动

    平动部分是较为简单的,最经典的公式:

    • 力$F=ma$
    • 速度$v=at$
    • 位移$s=vt$

    无须多言。

    转动

    刚体的转动可能令人感觉陌生,其实类比平动,大致相同。

    平动中,力$F$产生加速度$a$,进而影响速度$v$,进而影响位移$s$。

    转动中,力矩$M$产生角加速度$alpha$,进而影响角速度$omega$,进而影响角位移$ heta$。

    力矩$M=r imes F$,$r$是力臂,$F$是外力。

    但是,力矩$M$产生角加速度$alpha$,公式是$M=Jalpha$,这里就比平动复杂了。$J$是转动惯量,也能用$I$表示,类比于质量$m$。

    转动惯量

    求几何体${P_1,P_2…P_n}$的转动惯量。

    根据公式:

    $$I=frac{{m}}{6}frac{sum_{i=1}^{n}leftVert vec{P_{i+1}} imesvec{P_{i}} ightVert (vec{P_{i+1}^2}+vec{P_{i+1}}cdot vec{P_{i}}+vec{P_i^2})}{sum_{i=1}^{n}leftVert vec{P_{i+1}} imesvec{P_{i}} ightVert }$$

    力的交互

    重力

    物体在重力场中受到一个恒定方向、恒定大小的力$g$,将它算入总受力。

    碰撞

    两个物体间产生碰撞,这是物理引擎最核心的部分之一。

    一般来说,要解决这几个问题:

    1. 如何检测到碰撞的产生?
    2. 如何确定碰撞点及方向?
    3. 如何做精度修正?
    4. 如何解决“子弹”问题?

    解决了上述几个问题后,我们就可以求得发生碰撞的两个物体的总受力和力矩和,从而解析它们将要产生的平动和转动。

    涉及碰撞的内容很多,在后面会讲到。

    摩擦

    物体受空气阻力和地面摩擦力影响。地面摩擦力对物体产生的影响算入力矩和。

    总结

    实际上,一个涉及力学的物理引擎要做的最主要的事就是:

    求物体所受力和力矩,从而计算它将要发生的平动和转动。

    但如何求得力和力矩?这便是一个很复杂的问题了。像重力可以直接影响物体所受力,摩擦可以直接影响物体所受力矩,这些都很简单。较为复杂的就是两个物体间的碰撞了,在这里,物体引擎有一半以上的代码是用来计算碰撞的。

  • 相关阅读:
    欧拉函数
    uva10870 矩阵
    poj3233 矩阵等比数列求和 二分
    hdu4990 矩阵
    hdu4549 矩阵快速幂 + 欧拉降幂
    补矩阵的题目
    CodeForces 450B 矩阵
    hoj2662 状态压缩dp
    poj3254 状态压缩dp
    zoj2770 差分约束系统
  • 原文地址:https://www.cnblogs.com/bajdcc/p/5925922.html
Copyright © 2020-2023  润新知