碰撞检测GJK算法论文解析一

article/2025/9/24 23:59:17

碰撞检测GJK算法论文解析一

  • 碰撞检测
  • Objcet Representation And Distance
    • 1.涉及的概念
    • 2.内容详解
  • Preliminaries
    • 1.涉及的概念
    • 2.内容详解

碰撞检测

碰撞检测是3维游戏内必不可少的一个功能,有了碰撞检测,游戏才能显得更加真实。之前查找碰撞检测的资料,很多都提到了SAT以及GJK算法,但是少有对这两个算法进行深入解析的。于是本人花了一个星期左右去阅读GJK的论文,现在将论文内的细节进行整理,和大家分享。碰撞检测涉及到相当多数学知识,所以这个主题应该会有好几个部分组成。文章内可能会出现一些错的或者是不严谨的地方,也还请大家指正
论文地址:http://web.eecs.umich.edu/~grizzle/GilbertFest/Gilbert(58).pdf
论文的第一部分是总结前人工作以及对不同算法的比较,不涉及算法内容,因此跳过,直接从第二部分开始。还有一点是,公式后面的标号会和论文对应,所以可能不按顺序。

Objcet Representation And Distance

1.涉及的概念

  • 紧集(compact sets):紧集是指拓扑空间内的一类特殊点集,它们的任何开覆盖都有有限子覆盖。举个例子,实数的闭区间[a, b]即为紧集,而有理数的闭区间[c, d]不为紧集,这是因为实数是紧的,而有理数不是紧的。另一种表述是,如果一个有理数序列,其项为3,3.14,3.141,1.1415…可以知道,这个序列的极限是π,但是π不是有理数,也就是说由有理数构成的序列的极限可能不属于有理数,那么有理数的数轴上存在着无数的“洞”,既然有洞,那么肯定就不紧致。如果一个集合是紧的,那么它肯定是有界的。
  • 欧几里得距离(Euclidean length):欧几里得空间的度量函数,其实就是我们常用的计算向量长度的公式
  • 凸多面体(convex polytopes):简单来说就是如果一个多面体内任意两点之间的线段都包含在这个多面体内,那么这个多边形就是凸多面体。GJK算法适用于凸多面体,不适用与凹多面体(但是可以将凹多面体拆成多个凸多面体)。

2.内容详解

假设现在存在两个三维空间内的紧集 K A , K B ∈ R 3 K_A, K_B \in R^3 KA,KBR3,然后定义如下符号:
d ( K A , K B ) = m i n { ∣ x − y ∣ : x ∈ K A , y ∈ K B } ( 1 ) d(K_A, K_B ) = min \lbrace |x - y|: x \in K_A, y \in K_B \rbrace \kern3em \lparen1\rparen d(KA,KB)=min{xy:xKA,yKB}(1)显然,上式表示的是这两个集合中最近的点的距离,下图线段cd的长度就代表了两个圆最短的距离(为了画图方便,这里用了二维的图)
cd为两个圆之间的最短距离
如果集合A和B是由多个子集构成,这些子集满足:
K A = ⋃ i ∈ I A K i K B = ⋃ j ∈ I B K j ( 2 ) K_A = \bigcup_{i \in I_A} K_i \kern3em K_B = \bigcup_{j \in I_B} K_j \kern5em \lparen2\rparen KA=iIAKiKB=jIBKj(2)其中 I A I_A IA I B I_B IB是索引集(index set)。按照(1)式的定义,有:
d ( K A , K B ) = m i n { d i j : i ∈ I A , j ∈ I B } ( 3 ) d(K_A, K_B ) = min \lbrace d_{ij}: i \in I_A, j \in I_B \rbrace \kern3em \lparen3\rparen d(KA,KB)=min{dij:iIA,jIB}(3)其中 d i j d_{ij} dij定义为:
d i j = m i n { ∣ x − y ∣ : x ∈ K i , y ∈ K j } ( 4 ) d_{ij} = min \lbrace |x - y|: x \in K_i, y \in K_j \rbrace \kern4em \lparen4\rparen dij=min{xy:xKi,yKj}(4) d i j d_{ij} dij表示的是子集 K i K_i Ki K j K_j Kj之间的最短距离,然后返回公式(3)可得,两个集合之间的最短距离是各自子集最短距离的最小值。论文中的图很好的表现了这一点,这里我不作过多阐述。
红色箭头代表K2到KB的最短距离
接下来是r-球面扩展。举两个例子,三维空间中,点的r-球面扩展就是一个球,线段的r-球面扩展就是两头为球面的圆柱(上图中的 K 2 K_2 K2),这里的r指的是半径。其公式如下:
K r = { x : ∣ x − y ∣ ⩽ r , y ∈ K } ( 5 ) K^r = \lbrace x: |x - y| \leqslant r, y \in K\rbrace \kern3em \lparen5\rparen Kr={x:xyr,yK}(5)显然,在进行球面扩展之后两个闭集的最短距离可以表示为:
d ( K A r A , K B r B ) = ( d ( K A , K B ) − r A − r B ) + ( 6 ) d(K_A^{r_A}, K_B^{r_B} ) = (d(K_A, K_B ) - r_A - r_B)+ \kern3em \lparen6\rparen d(KArA,KBrB)=(d(KA,KB)rArB)+(6)其中+号是代表当值小于0时,值取0。
如果将公式(2)中的子集变成是球面扩展,那么结合公式(4)和公式(6)可得:
d ( K A , K B ) = m i n { ( d i j − r i − r j ) + : i ∈ I A , j ∈ I B } ( 8 ) d(K_A, K_B ) = min \lbrace (d_{ij} - r_i - r_j)+: i \in I_A, j \in I_B \rbrace \kern3em \lparen8\rparen d(KA,KB)=min{(dijrirj)+:iIA,jIB}(8)球面扩展可以在不少地方进行应用,像是要加壳的零件等。公式(8)提供了一个便利的计算方式。
接下来是讲当集合需要进行变换时该怎么处理。球面扩展和变换都稍微有点发散,所以这里不展开讲,有需要的话我在后面再进行补充。

Preliminaries

1.涉及的概念

  • 仿射集、仿射包、凸集、凸包、锥:具体的概念参考这篇文章:凸优化1——仿射集、凸集、锥。这几个概念相当重要,如果是想透彻地了解这个算法,那么必须弄懂这几个概念及其数学的表达
  • Minkowski difference(sum):这个概念并不复杂,如果有两个集合A和B,那么它们的Minkowski sum就是集合 { x A + x B , x A ∈ A , x B ∈ B } \lbrace x_A + x_B, x_A \in A, x_B \in B \rbrace {xA+xB,xAA,xBB},Minkowski difference就是集合 { x A − x B , x A ∈ A , x B ∈ B } \lbrace x_A - x_B, x_A \in A, x_B \in B \rbrace {xAxB,xAA,xBB}

2.内容详解

在这个小节里,集合X表示m维空间内的紧集,而Y表示m维空间的有限集,即Y中包含有限个顶点。那么集合X的仿射包表示为:
a f f X = { ∑ i = 1 l λ i x i , x i ∈ X , λ 1 + . . . + λ l = 1 } ( 11 ) aff X= \lbrace \sum_{i = 1}^l \lambda^ix_i,x_i \in X, \lambda^1 + ... + \lambda^l = 1 \rbrace \kern3em \lparen11\rparen affX={i=1lλixi,xiX,λ1+...+λl=1}(11)而集合X的凸包为:
c o X = { ∑ i = 1 l λ i x i , x i ∈ X , λ i ⩾ 0 , λ 1 + . . . + λ l = 1 } ( 12 ) coX= \lbrace \sum_{i = 1}^l \lambda^ix_i,x_i \in X,\lambda^i\geqslant 0 , \lambda^1 + ... + \lambda^l = 1 \rbrace \kern3em \lparen12\rparen coX={i=1lλixi,xiX,λi0,λ1+...+λl=1}(12)式(11)和式(12)只差了一个条件:凸包将系数 λ i \lambda^i λi限定为大于0。从上面的定义可以看出, a f f X affX affX是一个线性空间的平移。首先需要明确线性空间这个概念,线性空间也称为向量空间,具体的定义可以参考百度百科:向量空间。为什么说是平移,举个例子, a f f Y = Y + { y 1 } affY = \bold{Y} + \lbrace y_1 \rbrace affY=Y+{y1},其中 Y = { y 2 − y 1 , y 3 − y 1 , . . . , y v − y 1 } \bold{Y} = \lbrace y_2-y_1, y_3-y_1, ...,y_v-y_1 \rbrace Y={y2y1,y3y1,...,yvy1},所以可以知道,这个平移就是说 Y Y Y中后v-1个向量组成的向量空间按照向量 y 1 y_1 y1的方向进行平移。如果这时有 d i m a f f Y = d i m Y = v − 1 dim \space affY = dim \space \bold{Y} = v-1 dim affY=dim Y=v1,那么仿射包 a f f Y affY affY称为仿射无关(affinely independent)也就是说此时 Y \bold{Y} Y中的向量线性无关。否则,仿射包 a f f Y affY affY称为仿射相关,此时 Y \bold{Y} Y中的向量线性相关,那么肯定存在 Y Y Y的子集 Y ˉ \bar{Y} Yˉ使得 a f f Y ˉ = a f f Y aff\bar{Y} = affY affYˉ=affY,因为这个时候 Y \bold{Y} Y中最多只要v-2个向量即可满足条件。
然后由线性相关的概念可以知道,式(11)和式(12)中的 l l l最大值是这些向量所在的线性空间中的维度再加一,例如二维空间需要三个点才能组成面去覆盖二维的凸包,两个点就只能是线;三维空间需要4个点组成4面体才能覆盖三维的凸包,三个点就只能是面。严格的证明可以查看Caratheodory theorem的证明过程。
定义向量空间 X \bold{X} X到原点最近的点为 v ( X ) v(\bold{X}) v(X),则 v ( X ) v(\bold{X}) v(X)的长度的计算公式如下:
v ( X ) ∈ X , ∣ v ( X ) ∣ = m i n { ∣ x ∣ : x ∈ X } ( 13 ) v(\bold{X}) \in \bold{X}, |v(\bold{X})| = min\lbrace |x|: x \in \bold{X}\rbrace \kern3em \lparen13\rparen v(X)X,v(X)=min{x:xX}(13)一般来说 v ( X ) v(\bold{X}) v(X)可能会存在多个点,但是如果X是凸的,那么这个点是唯一的,那么结合式(12)可以得到:
v ( c o X ) = ∑ i = 1 l λ i x i , x i ∈ X , λ i ⩾ 0 , λ 1 + . . . + λ l = 1 ( 14 ) v(coX)= \sum_{i = 1}^l \lambda^ix_i,x_i \in X,\lambda^i\geqslant 0 , \lambda^1 + ... + \lambda^l = 1 \kern3em \lparen14\rparen v(coX)=i=1lλixi,xiX,λi0,λ1+...+λl=1(14)一般来说,上式中的 λ i \lambda^i λi x i x_i xi l l l都不是唯一的,但是有两点是很重要的,a)如果 v ( c o X ) = 0 v(coX) = 0 v(coX)=0,那么 l ⩽ m + 1 l \leqslant m+1 lm+1(m为向量空间的维度),这是因为原点落在凸包内,结合Caratheodory theorem可以知道结论成立;如果 v ( c o X ) ≠ 0 v(coX) \not= 0 v(coX)=0,那么 l ⩽ m l \leqslant m lm,因为这个时候原点在凸包之外,那么离原点最近的点一定是落在超平面(凸包的“边”)上。b) { x 1 , x 2 , . . . , x l } \lbrace x_1, x_2, ...,x_l \rbrace {x1,x2,...,xl}仿射无关,这个结论的证明和Caratheodory theorem的相似
定义向量空间 X \bold{X} X内的函数 h X ( η ) : R m → R h_X(\eta):R^m \to R hX(η):RmR
h X ( η ) = m a x { x ⋅ η : x ∈ X } ( 15 ) h_X(\eta) = max\lbrace x · \eta: x \in \bold{X} \rbrace \kern3em \lparen15\rparen hX(η)=max{xη:xX}(15)这个函数返回获取向量空间内离特定向量最远的点。然后将式(15)改写成:
h X ( η ) = s X ( η ) ⋅ η , s X ( η ) ∈ X ( 16 ) h_X(\eta) = s_X(\eta) ·\eta,s_X(\eta) \in \bold{X} \kern3em \lparen16\rparen hX(η)=sX(η)η,sX(η)X(16)容易证明 h X = h c o X , s X = s c o X h_X = h_{coX},s_X = s_{coX} hX=hcoX,sX=scoX,因为这时候的点一般都是在凸包的顶点上,而这些顶点也必定属于原来的向量空间(凸包的定义),后面有图会体现这点。
对于有限集 Y Y Y,则有:
h c o Y = h Y = m a x { y i ⋅ η : i = 1 , 2 , . . . , v } s c o Y = s Y = y j , y j ⋅ η = h Y ( η ) ( 17 ) h_{coY} = h_Y = max\lbrace y_i · \eta: i = 1,2,...,v \rbrace \space s_{coY} = s_Y = y_j, y_j ·\eta = h_Y(\eta)\kern3em \lparen17\rparen hcoY=hY=max{yiη:i=1,2,...,v} scoY=sY=yj,yjη=hY(η)(17)上面的概念可以用下面这个图来进行理解:
在这里插入图片描述
我认为上面这个图还是比较清晰的,主要是注意各个符号的定义即可。
接下来我们返回公式(4),根据上面提到的概念去求出 d i j d_{ij} dij,为了简便,设 i = 1 , j = 2 i = 1,j = 2 i=1,j=2。根据公式(4)有:
d 12 = m i n { ∣ z ∣ : z ∈ K } = ∣ v ( K ) ∣ , K = K 1 − K 2 ( 18 ) d_{12} = min\lbrace |z|: z \in K \rbrace = |v(K)|, K = K_1 - K_2\kern3em \lparen18\rparen d12=min{z:zK}=v(K),K=K1K2(18)要求 d i j d_{ij} dij,首先要求出 h K h_K hK s K s_K sK,公式如下:
h K ( η ) = h K 1 ( η ) + h K 2 ( − η ) , s K ( η ) = s K 1 ( η ) − s K 2 ( − η ) ( 21 ) h_K(\eta) = h_{K1}(\eta) + h_{K2}(-\eta), s_K(\eta) = s_{K1}(\eta) - s_{K2}(-\eta)\kern3em \lparen21\rparen hK(η)=hK1(η)+hK2(η),sK(η)=sK1(η)sK2(η)(21)直接这么看有点抽象,用文字描述就是: h K ( η ) h_K(\eta) hK(η)等于K1沿着 η \eta η方向最长的投影距离减去K2沿着 η \eta η方向最短的投影距离,减是因为 h K 2 ( − η ) h_{K2}(-\eta) hK2(η) = − h K 2 ( η ) -h_{K2}(\eta) hK2(η)。通过选取不同的 η \eta η可以得到不同的点,如果这些点的凸包包含原点,那么说明K1和K2相交(说明K1和K2存在相同的点)。
现在最关键的问题就是如何有效地选取 η \eta η,这一块将在第二部分中解决。


http://chatgpt.dhexx.cn/article/SxttoeD5.shtml

相关文章

GJK之判断是否相交

由于排版问题,新文章已经更新到 本文新地址 原文地址: http://www.codezealot.org/archives/88 一、 介绍: GJK和SAT一样,只适用于凸多边形。GJK更为强大的地方在于,它可以通过“支持函数”(稍后讨论)支持所有的形状。因此,和SA…

引擎开发_ 碰撞检测_GJK 算法详细介绍

概述 和SAT(分离轴定理)算法一样,GJK算法也只对凸体有效。 GJK算法的优势是:通过support函数(后面会详细讲述),从而支持任何凸体形状之间的碰撞检测;相比SAT算法,你不需要一些额外的操作&#x…

Planning-碰撞检测之GJK

原文:dyn4j:GJK (Gilbert–Johnson–Keerthi) 目录 1. Minkowski Sum(明可夫斯基和)2. Simplex3. support函数4. 构建Simplex G J K GJK GJK和 S A T SAT SAT一样用于检测凸多边形,和 S A T SAT SAT不同, G J K GJK GJK可以处理任意形状的凸多边形&#…

GJK算法

转自:http://blog.sina.com.cn/s/blog_833d50630100xw1r.html GJK算法最初用来求三维空间中凸多面体的距离(即最近距离),也因此经常用来做碰撞检测(距离是否为0)。后被推广到n维空间中求凸包之间的距离&…

碰撞检测GJK算法论文解析二

碰撞检测GJK算法论文解析二 The Theoretical Algorithm内容详解 初探The Distance Subalgorithm内容详解 Appendix Ⅱ涉及的概念内容详解 接上文,本篇文章讲解GJK算法论文的第四、第五部分前半部分,这是整个算法最为核心的部分。第四部分阐述了算法的核心…

碰撞检测GJK算法论文解析三

碰撞检测GJK算法论文解析三 再探Appendix Ⅱ内容详解 再探The Distance Subalgorithm内容详解过程1过程2过程3 这里要先纠正上篇文章的一些错误,就是上篇文章的最后其实并没有证明定理3,而只是给出了仿射集系数向量 λ \lambda λ的解的形式,…

GJK碰撞检测(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

物理引擎学习04-GJK计算多边形之间的最近距离

计算多边形之间的最近距离,才是GJK算法原本的目的。只有两个多边形不相交,计算最近距离才有效。如果相交,则最近距离无效,但是可以使用EPA算法要计算碰撞深度。本文的写作目的,主要是对GJK算法的理解和应用。对算法本身…

python碰撞检测算法_GJK碰撞检测算法

现实世界里我们对于是否碰撞的判断可以说极其容易而且准确,比如下图。在二进制的世界里,一切就没这么直观了。 GJK(Gilbert-Johnson-Keerthi Distance Algorithm) GJK 就是此次要实现的碰撞检测算法。如果对碰撞算法有过了解的话,大概率听过另一个碰撞检测算法 SAT(Separati…

【计算几何】凸多面体重叠判断算法:GJK 算法详解 C++代码实现二维情形的凸多边形重叠判断

文章目录 一、GJK 算法简介二、前置知识2.1 二维向量的点乘和叉乘2.2 三维向量叉乘2.3 凸多边形2.4 闵可夫斯基差2.5 单纯形2.6 Support 函数 三、GJK 算法讲解3.1 熟悉 GJK 算法流程3.1.1 多边形重叠的情形3.1.2 多边形不重叠的情形 3.2 总结 GJK 算法步骤3.3 讲解 GJK 算法细…

GJK 算法

GJK 算法(Gilbert–Johnson–Keerthi) 翻译自:http://www.dyn4j.org/2010/04/gjk-gilbert-johnson-keerthi/ 今天,我将讨论dyn4j项目随附的其他碰撞检测算法。您可以找到很多GJK文档,但是其中很多实际上是技术性的,主要是因为它…

碰撞检测算法之GJK算法

简介 参考: 碰撞检测算法之GJK算法 - 知乎 (zhihu.com) 运筹优化】凸多面体重叠判断算法:GJK 算法详解 & C代码实现二维情形的凸多边形重叠判断_c 凸多边形_WSKH0929的博客-CSDN博客 物理引擎学习03-GJK碰撞检测算法基础gjk算法游蓝海的博客-CSDN博客…

物理引擎学习05-GJK和EPA计算穿透向量

EPA,是扩展多边形算法(Epanding Polytop Algorithm) ,用来计算两个多边形碰撞的穿透深度和方向,可用于将两个发生碰撞的多边形分离。本文的写作目的,主要是对GJK和EPA算法的理解和应用。对算法本身感兴趣的朋友,可以阅…

物理引擎学习03-GJK碰撞检测算法基础

GJK是由Gilbert,Johnson,Keerthi 三位前辈发明的,用来计算两个凸多面体之间的碰撞检测,以及最近距离。GJK算法可以在O(MN)的时间复杂度内,检测出碰撞,算法在每次迭代的过程中,都会优先选择靠近原…

碰撞检测——GJK算法

目录 碰撞检测——GJK算法 1.GJK算法的原理及思想 1.1 Minkowski Sum(明可夫斯基和) 1.2 Simplex 1.3 support函数 1.4 构建Simplex 2. GJK算法步骤 3. GJK算法的优缺点分析 4. GJK算法与其他相关算法的比较分析 4.1 GJK算法和SAT算法的比较 …

QPM 之悬浮窗设置信息

QPM 开源地址:https://github.com/ZhuoKeTeam/QPM 更多实用信息: 手机的基本信息AndroidManifest.xml 信息App 中所有的 SharePreference 信息可配置的开关网络接口 手机基础信息 再也不用 去手机的复杂界面查看各种数据;再也不用 下载 辅…

QPM访谈问题

QPM:Quantitative Project Management,量化项目管理 一、访谈问题 1、请简要介绍贵司的QPM管理的管理方式? 依据公司整体商业目标和CMMI要求,制定和部署了《量化项目管理过程》和相关的指南、模板。 在项目执行中,…

QPM 性能监控组件——总篇

QPM (Quality Performance Monitor) 是一个质量性能监控组件,可以很方便的查看当前 App 的性能和常用数据。目前主要运行在 Android 平台上,通过集成 QPM 组件,可以在 App 中通过悬浮窗可视化相关实时数据。意在帮助广…

IDEA快捷键显示参数提示

一、IDEA显示参数的提示 1、理想状态是这样 2、某度了半天 都是让画show parameter 那个勾的,不是我想要的 IDEA默认的快捷键提示是 " ctrl p",但是我改成eclipse的快捷键后就没有提示了 File---->settings---->keymap 需要给ecli…

Idea设置代码自动提示快捷键

使用eclipse都习惯使用快捷键ALT/ 来代码自动提示,后来使用IntelliJ Idea这个快捷键并不管用,十分不便,这里记录如何使更改idea代码自动提示快捷键。 哪个是代码自动提示快捷键 File–》Settings–》KeyMap(快捷键ctrlalts)进入快捷键设置界…