返回

文章详情

用散度定理快速计算体积的幽默方法

Hacker News2026年8月28日 09:00

2018年2月16日(不,这里没有笑话。)以下介绍了一种用于简单封闭三角化3D网格的快速体积计算算法。这一假设是散度定理的结果。进一步的扩展可能会推广到其他网格,但目前不在讨论范围内。我们首先给出体积的定义为在常数1的区域上的三重积分:V=∭R1dV=∭R1 ext{d}V令𝐅是一个在ℝ3中的函数,满足其散度等于1。为了本论文的目的,我们选择:𝐅(x,y,z)=<x,0,0> ext{F}(x, y, z) = <x, 0, 0>可以很容易地验证, ext{div} extbf{F} = rac{ ext{d}F}{ ext{d}x} + rac{ ext{d}F}{ ext{d}y} + rac{ ext{d}F}{ ext{d}z} = 1 + 0 + 0 = 1因此,V=∭R1dV=∭R ext{div} extbf{F}(x,y,z)dV=∭R ext{d}V=∭R ext{div} extbf{F}(x, y, z) ext{d}V根据散度定理,这等于表面积积分:V=∬S extbf{F}(x,y,z) ext{d} extbf{S} 这个表面积积分是对3D网格的表面S定义的,等于其分段三角形部分的总和。令Ti表示网格中的第i个三角形的表面。那么,V=∑i=0∬Ti extbf{F}(x,y,z) ext{d} extbf{S} V = ext{∑}_{i = 0} ext{∬}_{T_i} extbf{F}(x, y, z) ext{d} extbf{S} 令Tin表示第i个三角形的第n个顶点。让Δ1等于Ti1减去Ti0的向量差,Δ2同样等于Ti2减去Ti0。每个个体三角形Ti可以参数化为:𝐫(u,v)=Ti0+uΔ1+vΔ2 由于简单的微分,可以得出:𝐫u=Δ1 ext{r}_u = ext{Δ}_1 𝐫v=Δ2 ext{r}_v = ext{Δ}_2 因此,𝐫u×𝐫v=Δ1×Δ2 ext{r}_u imes ext{r}_v = ext{Δ}_1 imes ext{Δ}_2 因此,表面积积分可以用此参数化重新编写,按需替换𝐅的定义:V=∑i=0∬Ti𝐅(x,y,z)(𝐫u×𝐫v)dA=∑i=0∬Ti𝐅(x,y,z)( ext{Δ}i1× ext{Δ}i2)dA=∑i=0∬Ti<x,0,0>( ext{Δ}i1× ext{Δ}i2)dA=∑i=0∬Ti<x, 0, 0> ext{Δ}_{i1} imes ext{Δ}_{i2} dA 这个叉乘在整个三角形内是常数,并且容易从顶点数据中计算。只有叉乘的X分量应该被计算;由于与𝐅的零分量的点积,其他分量等于零。因此,V可以重新编写为:V=∑i=0( ext{Δ}i1× ext{Δ}i2)x∬Ti x dA=∑i=0 ( ext{Δ}_{i1} imes ext{Δ}_{i2})_x ext{∬}_{T_i} x dA我们现在关注表面积积分∬Ti x dA。展开参数化可以得到:∬Ti x dA=∫01∫0u x dv du=∫01∫0u(Ti0x+uΔi1x+vΔi2x) dv du这个积分可以直接计算,将顶点数据视为常量:∫01∫01−u(Ti0x+uΔi1x+vΔi2x) dv du=Ti0x∫01∫01−u dv du+Δi1x∫01∫01−u u dv du+Δi2x∫01∫01−u v dv du=Ti0x( rac{1}{2}) + ext{Δ}_{i1x}( rac{1}{6}) + ext{Δ}_{i2x}( rac{1}{6})=Ti0x( rac{12}) + (Ti1x-Ti0x)( rac{16}) + (Ti2x-Ti0x)( rac{16})=Ti0x( rac{1}{2}) + (Ti1x-Ti0x)( rac{1}{6}) + (Ti2x-Ti0x)( rac{1}{6})=Ti0x( rac{16})+(Ti1x)( rac{16})+(Ti2x)( rac{16})=Ti0x( rac{1}{6}) +(Ti1x)( rac{1}{6}) + (Ti2x)( rac{1}{6})=16(Ti0x+Ti1x+Ti2x)= rac{1}{6}(Ti0x+Ti1x+Ti2x) 将其代入原始和中,并拉出一个常数因子16 rac{1}{6} 以避免内循环除法,得到了体积的以下紧凑公式:V=16∑i=0( ext{Δ}i1 imes ext{Δ}i2)x(Ti0x+Ti1x+Ti2x)V = rac{1}{6} ext{∑}_{i = 0} ext{( ext{Δ}_{i1} imes ext{Δ}_{i2})_x (T_{i0x} + T_{i1x} + T_{i2x}) }性能分析最终算法不包含数值积分或微分。与计算体积的常见简单算法相比,后者相当于渲染网格并采样渲染,是一种昂贵的操作,而该算法仅在三角形的循环内有一个单独的循环。因此,这种体积计算算法的时间复杂度是O(n),其中n是三角形的数量。此外,每个三角形的计算同样高效:考虑到叉乘的自然展开,内部部分包含七个加法和三个乘法。循环外部只进行一次乘法。因此,对于n个三角形的网格,该算法需要8n−18n - 1个加法和3n+13n + 1个乘法,或11n11n次浮点操作。这非常快。作为一个大致的数字,如果在高性能的60帧每秒的应用程序中每帧都需要计算体积,

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡