计算正余弦函数 sin: 当 `|x|` 充分小时, 近似有 `sin x ~~ x`; 否则使用三倍角公式递推. cos: 当 `|x|` 充分小时, 近似有 `cos x ~~ 1-x^2/2`; 否则使用二倍角公式递推.
Cordic 算法 是一种计算 `arctan x` 的查表法.
事先将 `theta_n = arctan 2^-n`, `n = 0, 1, 2, cdots` 存于表中,
然后逐步旋转逼近. 此方法可以逼近任意一个不超过 `sum_(n ge 0) arctan
2^-n ~~ 99.88^@` 的角度.
从平面向量的旋转公式
`bm v_1 = [cos theta, -sin theta; sin theta, cos theta] bm v`
两边同除以 `cos theta` 得到伪旋转公式:
`bm v' = [1, -tan theta; tan theta, 1] bm v`.
取 `bm v_n = (x_n, y_n)`, `tan theta_n = 2^(-n)`. 上式写成
`{ x_(n+1) = x_n - y_n // 2^n;
y_(n+1) = y_n + x_n // 2^n :}`
当 `|y_n|` 足够小时就中止迭代.
结果约为: 63.43494882292201 度
判断多边形方向是否为顺时针 (面积法) [来自 github copilot] 用 Green 公式求边界的曲线积分 `int_(del S) -2y dx = 2 iint_S dx dy`, 若结果为负, 说明曲线为顺时针.
判断点是否在多边形内 (引射线法) [来自 chatgpt] 从待判断的点向右发射一条射线, 若交点数为奇数, 则点在多边形内. 该算法适用于顺时针和逆时针的多边形, 甚至也适用于自相交的多边形 (重叠部分按异或计算). 注意, 按此算法, 边界上的点不算在多边形内.
判断线段是否相交 (解方程法)
直接计算两直线的交点坐标, 把它表示为参数 t
的函数. 两线段相交当且仅当直线相交,
且 0 ≤ t ≤ 1
.
判断线段是否相交 (四边形法) 以两条线段为对角线, 张成一个四边形. 则两线段相交当且仅当该四边形是凸四边形. 具体说, 就是 p3, p4 位于直线 p1-p2 的两侧, 且 p1, p2 位于直线 p3-p4 的两侧.
length
是向量长度 dot
, cross
分别是点乘与叉乘.
length(p1 - p2)
. 由于球体就是有厚度的点, 此公式也可以计算两球体的距离.
dot(p - q, n)
, 取绝对值就得到距离. 同上所述, 此公式可以计算球体到平面的距离.
cross(p - q, v)
, 叉乘的结果是一个向量, 取向量的模长就得到距离.
dot(p-a, b-a) < 0
;dot(p-b, a-b) < 0
;q = x1 v1 + x2 v2 + x3 v3
, 其中 x1 + x2 + x3 = 1
.
(x1, x2, x3)
就称为它的重心坐标.
重心坐标的一个重要性质是, 它的 3 个分量之比等于该顶点相对的小三角形的有向面积之比.
下面的公式中 area
代表三角形的有向面积:
x1 / area(q, v2, v3) = x2 / area(q, v3, v1) = x3 / area(q, v1, v2)
3 个小三角形有向面积之和等于三角形的面积 A, 所以
A * x1 = area(q, v2, v3) = length(v2 - v3) * d23 / 2
,
d23
是 q 点到边 v2-v3 的有向距离. 同理可以求出 q 点到其他两边的有向距离.
综上, 点 q 到三角形的距离等于它到 3 个顶点、3 条边的距离的最小值.
随着场景复杂度的提高, 可以为场景生成 BVH (层次包围体树, Bounding Volume Hierarchy), 如四叉树, 八叉树等. 我们将待检测对象按空间位置区分管理, 每次只需检测同组对象的碰撞即可.