浅析计算机图形学经典模型简化算法——QEM

1,192 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第20天,点击查看活动详情。你可以简单浏览一下目录,有需要的阅读,写文章不易,阅读之前请给我点个赞吧~

本文主要为对论文《Surface Simplification Using Quadric Error Metrics Surface Simplification Using Quadric Error Metrics》的理解与总结,旨在帮助相关领域的人更好的理解 QEM 这个经典的模型简化算法。

一、为什么有这种算法

1.1 外界的需求

计算机图形学中的许多应用需要复杂的、高度详细的模型。然而,实际需要的详细程度可能有很大的不同。为了控制处理时间,通常需要使用近似来代替过分详细的模型。

1.2 此算法的功能

这里讲述的就是 Michael Garland 提出的一种曲面简化算法,它可以快速生成高质量的多边形模型近似。

1.3 算法设计思路

该算法使用 顶点对迭代 收缩 来简化模型,并使用 二次矩阵(quadric matrices) 保持曲面误差逼近。

通过收缩任意顶点对(不仅仅是边),我们的算法能够连接模型中不相连的区域。这可以促进更好的近似,无论是视觉上还是几何误差上。为了允许拓扑连接,我们的系统还支持非流形(non-manifold)曲面模型。

二、相关概念

2.1 有效对

  • (v1,v2)\left(\mathbf{v}_1, \mathbf{v}_2\right) 是一条边
  • 或者 v1v2<t\left\|\mathbf{v}_1-\mathbf{v}_2\right\|<t,这里 tt 是阈值(threshold)参数 t=0t = 0 ,是纯的边收缩高一点,允许非连接点成为pair 如果它太高,模型中分散的部分可能会被连接起来,这可能是不希望的,它可能会产生O(n2)对 在迭代收缩过程中,我们必须跟踪有效对的集合。对于每个顶点,我们将其作为成员的对集合关联起来。

2.2 边对选择

当我们进行收缩(v1,v2)v\left(\mathbf{v}_1, \mathbf{v}_2\right) \rightarrow \overline{\mathbf{v}}时,v1\mathbf{v}_1不仅获得了所有与v2\mathbf{v}_2相连的边,它还将v2\mathbf{v}_2的对集合并到自己的集合中。在一个有效pair中出现的每一个v2\mathbf{v}_2v1\mathbf{v}_1替换,重复的pair被删除。

2.3 二次型近似误差(Approximating Error With Quadrics)

为每个顶点关联一个平面集,比如关于下图中间的点 v 的平面集中,包含如图所示的六个面。

image.png

定义点v\mathbf{v}处的误差,是该点到它的平面集中的各个平面的距离的平方的总和 Δ(v)=Δ([vxvyvz1])=p planes (v)(pv)2\Delta(\mathbf{v})=\Delta\left(\left[\begin{array}{llll}v_x & v_y & v_z & 1\end{array}\right]^{\top}\right)=\sum_{\mathbf{p} \in \text { planes }(\mathbf{v})}\left(\mathbf{p}^{\top} \mathbf{v}\right)^2

这里 p=[abcd]\mathbf{p}=\left[\begin{array}{llll}a& b & c & d\end{array}\right]^{\top}代表了 ax+by+cz+d=0a x+b y+c z+d=0 这个方程定义的平面,其中 a2+b2+c2=1a^2+b^2+c^2=1. 因为 pp 的转置 vv 是个数值,所以等价于

Δ(v)=p planes (v)(vp)(pv)=p planes (v)v(pp)v=v(p planes (v)Kp)v\begin{aligned} \Delta(\mathbf{v}) &=\sum_{\mathbf{p} \in \text { planes }(\mathbf{v})}\left(\mathbf{v}^{\top} \mathbf{p}\right)\left(\mathbf{p}^{\top} \mathbf{v}\right) \\ &=\sum_{\mathbf{p} \in \text { planes }(\mathbf{v})} \mathbf{v}^{\top}\left(\mathbf{p p}^{\top}\right) \mathbf{v} \\ &=\mathbf{v}^{\top}\left(\sum_{\mathbf{p} \in \text { planes }(\mathbf{v})} \mathbf{K}_{\mathbf{p}}\right) \mathbf{v} \end{aligned}

这里

Kp=pp=[a2abacadabb2bcbdacbcc2cdadbdcdd2]\mathbf{K}_{\mathbf{p}}=\mathbf{p p}^{\top}=\left[\begin{array}{llll} a^2 & a b & a c & a d \\ a b & b^2 & b c & b d \\ a c & b c & c^2 & c d \\ a d & b d & c d & d^2 \end{array}\right]

QQ 就是

pplanes(v)Kp\sum_{\mathbf{p} \in \mathrm{planes}(\mathbf{v})} \mathbf{K}_{\mathbf{p}}

顶点 v=[vxvyvz1]\mathbf{v}=\left[\begin{array}{llll}v_x & v_y & v_z & 1\end{array}\right]^{\top}

顶点处的误差的二次型表达:

Δ(v)=vQv\Delta(\mathbf{v})=\mathbf{v}^{\top} \mathbf{Q} \mathbf{v}

这里

vQv=q11x2+2q12xy+2q13xz+2q14x+q22y2+2q23yz+2q24y+q33z2+2q34z+q44\begin{aligned} \mathbf{v}^{\top} \mathbf{Q v} &=q_{11} x^2+2 q_{12} x y+2 q_{13} x z+2 q_{14} x+q_{22} y^2 \\ &+2 q_{23} y z+2 q_{24} y+q_{33} z^2+2 q_{34} z+q_{44} \end{aligned}

水平面

Δ(v)=ϵ\Delta(\mathbf{v})=\epsilon

这是所有关于 QQ 的误差为 ϵ\epsilon 的点的集合

对于给定的坍缩(v1,v2)v\left(\mathbf{v}_1, \mathbf{v}_2\right) \rightarrow \overline{\mathbf{v}},我们必须计算出一个新的在点 vˉ\bar{v} 处的误差Qˉ\bar{Q},我们可以选择使用简单的加法规则 Qˉ=Q1+Q2\bar{Q} = Q_1 + Q_2

为了展示坍缩(v1,v2)v\left(\mathbf{v}_1, \mathbf{v}_2\right) \rightarrow \overline{\mathbf{v}},我们必须 为 v\overline{\mathbf{v}} 选择点,一个简单的规则:

v1\mathbf{v}_1 ,v2\mathbf{v}_2 ,(v1+v2)/2\left(\mathbf{v}_1+\mathbf{v}_2\right) / 2 选择他们谁能产生最小的 Δ(v)\Delta(\overline{\mathbf{v}}) .由于误差函数 Δ(v)\Delta(\overline{\mathbf{v}}) 是一个二次型,找最小值是线性问题,我们通过求偏导找最小值

Δ/x=Δ/y=Δ/z=0\partial \Delta / \partial x=\partial \Delta / \partial y=\partial \Delta / \partial z=0
[q11q12q13q14q12q22q23q24q13q23q33q340001]v=[0001]\left[\begin{array}{cccc} q_{11} & q_{12} & q_{13} & q_{14} \\ q_{12} & q_{22} & q_{23} & q_{24} \\ q_{13} & q_{23} & q_{33} & q_{34} \\ 0 & 0 & 0 & 1 \end{array}\right] \overline{\mathbf{v}}=\left[\begin{array}{l} 0 \\ 0 \\ 0 \\ 1 \end{array}\right]

它是齐次的,Q矩阵可逆的话,有

v=[q11q12q13q14q12q22q23q24q13q23q33q340001]1[0001]\overline{\mathbf{v}}=\left[\begin{array}{cccc} q_{11} & q_{12} & q_{13} & q_{14} \\ q_{12} & q_{22} & q_{23} & q_{24} \\ q_{13} & q_{23} & q_{33} & q_{34} \\ 0 & 0 & 0 & 1 \end{array}\right]^{-1}\left[\begin{array}{l} 0 \\ 0 \\ 0 \\ 1 \end{array}\right]

Q矩阵不可逆的话,我们沿着v1\mathbf{v}_1 v2\mathbf{v}_2 的线段去找,如果这也失败了,我们就回退在中点和终点之间找 v\overline{\mathbf{v}}

image.png

三、算法步骤

我们的简化算法是建立在边坍缩和二次误差度量的基础上的。当前的实现表示了我们邻接图结构的模型:顶点、边和面都显式地表达并链接在一起。为了跟踪有效边对的集合,每个顶点都维护一个与它自己相关的边对集合。算法本身可以快速概括如下:

步骤

  1. 计算所有初始顶点的 QQ 矩阵
  2. 选择有效的边对
  3. 为每一个有效边对 (v1,v2)\left(\mathbf{v}_1, \mathbf{v}_2\right) 计算最优的坍缩目标 v\overline{\mathbf{v}} ,目标顶点的误差v(Q1+Q2)v\overline{\mathbf{v}}^{\top}\left(\mathbf{Q}_1+\mathbf{Q}_2\right) \overline{\mathbf{v}} 成为了边坍缩的代价。
  4. 按照边对的代价,从小到大将所有的对排列,小的在上。
  5. 迭代地从堆中移除代价最小的边对(v1,v2)\left(\mathbf{v}_1, \mathbf{v}_2\right) ,收缩这个边对(pair),并更新四中所有与 v1\mathbf{v}_1 相连的边对的代价(cost)。

[1] Garland M , Heckbert P S . Surface simplification using quadric error metrics[J]. ACM SIGGRAPH Computer Graphics, 1997, 1997:209-216.