3D 碰撞检测

这篇具有很好参考价值的文章主要介绍了3D 碰撞检测。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

推荐:使用 NSDT场景编辑器快速搭建3D应用场景

3D 碰撞检测,3D,碰撞检测

轴对齐边界框

与 2D 碰撞检测一样,轴对齐边界框 (AABB) 是确定两个游戏实体是否重叠的最快算法。这包括将游戏实体包装在一个非旋转(因此轴对齐)的框中,并检查这些框在 3D 坐标空间中的位置以查看它们是否重叠。

3D 碰撞检测,3D,碰撞检测

由于性能原因,存在轴对齐约束。两个非旋转框之间的重叠区域可以仅通过逻辑比较来检查,而旋转框需要额外的三角运算,这些操作的计算速度较慢。如果您有将要旋转的实体,则可以修改边界框的尺寸,使其仍环绕对象,或者选择使用其他边界几何类型,例如球体(对旋转不变)。下面的动画 GIF 显示了 AABB 的图形示例,该示例调整其大小以适应旋转实体。盒子不断改变尺寸,以紧密贴合其中包含的实体。

3D 碰撞检测,3D,碰撞检测

注意:查看 使用 THREE.js 进行边界体积碰撞检测 一文,了解此技术的实际实现。

点 vs. AABB

检查一个点是否在 AABB 内非常简单——我们只需要检查点的坐标是否在 AABB 内;分别考虑每个轴。如果我们假设 P x、P y 和 Pz 是点的坐标,B minX–B maxX、B minY–B maxY 和 B minZB maxZ 是 AABB 每个轴的范围,我们可以使用以下公式计算两者之间是否发生了碰撞:

3D 碰撞检测,3D,碰撞检测

或者在 JavaScript 中:

.JS复制到剪贴板

function isPointInsideAABB(point, box) {
  return (
    point.x >= box.minX &&
    point.x <= box.maxX &&
    point.y >= box.minY &&
    point.y <= box.maxY &&
    point.z >= box.minZ &&
    point.z <= box.maxZ
  );
}

AABB vs. AABB

检查一个 AABB 是否与另一个 AABB 相交类似于点测试。我们只需要使用框的边界对每个轴进行一次测试。下图显示了我们将在 X 轴上执行的测试 — 基本上,范围 A minX–A maxX 和 B minX–B maxX 是否重叠?

3D 碰撞检测,3D,碰撞检测

从数学上讲,这看起来像这样:

3D 碰撞检测,3D,碰撞检测

在 JavaScript 中,我们会使用这个:

.JS复制到剪贴板

function intersect(a, b) {
  return (
    a.minX <= b.maxX &&
    a.maxX >= b.minX &&
    a.minY <= b.maxY &&
    a.maxY >= b.minY &&
    a.minZ <= b.maxZ &&
    a.maxZ >= b.minZ
  );
}

边界球体

使用边界球体来检测碰撞比 AABB 稍微复杂一些,但测试起来仍然相当快。球体的主要优点是它们对旋转是不变的,因此如果包裹的实体旋转,边界球体仍将相同。它们的主要缺点是,除非它们要包装的实体实际上是球形的,否则包装通常不是很好的拟合(即用边界球体包裹一个人会导致很多误报,而 AABB 会是更好的匹配)。

点与球体

要检查球体是否包含点,我们需要计算点和球心之间的距离。如果此距离小于或等于球体的半径,则该点位于球体内部。

3D 碰撞检测,3D,碰撞检测

考虑到两点 A 和 B 之间的欧几里得距离为

3D 碰撞检测,3D,碰撞检测

我们的点与球体碰撞检测公式将如下所示:

3D 碰撞检测,3D,碰撞检测

或者在 JavaScript 中:

.JS复制到剪贴板

function isPointInsideSphere(point, sphere) {
  // we are using multiplications because is faster than calling Math.pow
  const distance = Math.sqrt(
    (point.x - sphere.x) * (point.x - sphere.x) +
      (point.y - sphere.y) * (point.y - sphere.y) +
      (point.z - sphere.z) * (point.z - sphere.z),
  );
  return distance < sphere.radius;
}

注意:上面的代码具有平方根,计算起来可能很昂贵。避免这种情况的简单优化包括将平方距离与平方半径进行比较,因此优化方程将涉及 。distanceSqr < sphere.radius * sphere.radius

球体与球体

球体与球体测试类似于点与球体测试。我们在这里需要测试的是球体中心之间的距离小于或等于它们的半径之和。

3D 碰撞检测,3D,碰撞检测

在数学上,这看起来像:

3D 碰撞检测,3D,碰撞检测

或者在 JavaScript 中:

.JS复制到剪贴板

function intersect(sphere, other) {
  // we are using multiplications because it's faster than calling Math.pow
  const distance = Math.sqrt(
    (sphere.x - other.x) * (sphere.x - other.x) +
      (sphere.y - other.y) * (sphere.y - other.y) +
      (sphere.z - other.z) * (sphere.z - other.z),
  );
  return distance < sphere.radius + other.radius;
}

球体 vs. AABB

测试球体和AABB是否碰撞稍微复杂一些,但仍然简单快捷。一种合乎逻辑的方法是检查 AABB 的每个顶点,对每个顶点进行点与球面测试。然而,这是矫枉过正的——测试所有顶点是不必要的,因为我们只需计算 AABB 的最近点(不一定是顶点)和球体中心之间的距离,看看它是否小于或等于球体的半径。我们可以通过将球体的中心钳制到 AABB 的极限来获得此值。

3D 碰撞检测,3D,碰撞检测

在 JavaScript 中,我们会像这样做这个测试:

.JS复制到剪贴板

function intersect(sphere, box) {
  // get box closest point to sphere center by clamping
  const x = Math.max(box.minX, Math.min(sphere.x, box.maxX));
  const y = Math.max(box.minY, Math.min(sphere.y, box.maxY));
  const z = Math.max(box.minZ, Math.min(sphere.z, box.maxZ));

  // this is the same as isPointInsideSphere
  const distance = Math.sqrt(
    (x - sphere.x) * (x - sphere.x) +
      (y - sphere.y) * (y - sphere.y) +
      (z - sphere.z) * (z - sphere.z),
  );

  return distance < sphere.radius;
}

使用物理引擎

3D物理引擎提供碰撞检测算法,其中大多数也基于边界体积。物理引擎的工作方式是创建一个物理身体,通常附加到它的视觉表示上。该主体具有速度、位置、旋转、扭矩等属性,以及物理形状。此形状是碰撞检测计算中考虑的形状。

原文链接:3D 碰撞检测 (mvrlink.com)文章来源地址https://www.toymoban.com/news/detail-702107.html

到了这里,关于3D 碰撞检测的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 深入分析物理引擎后,他写了一个轻量的 Cocos 3D 碰撞检测优化方案

    引言: 碰撞检测是游戏开发中一个非常重要的技术点,优化碰撞检测性能,是提升游戏体验不可或缺的一环。开发者「我叫98K」写了一个轻量碰撞系统,用以改善 3D 游戏在不同平台遇到的碰撞性能问题和包体问题。下载和在线体验地址见文末。 98K物理-轻量碰撞系统是一个高

    2024年02月03日
    浏览(38)
  • yolov5车道线检测+测距(碰撞检测)

    相关链接 1. 基于yolov5的车道线检测及安卓部署 2. YOLOv5#

    2024年02月08日
    浏览(39)
  • Unity碰撞器检测失败

    1.1tag错误 看看是不是误删tag或者tag改变导致碰撞器无法检测 2.1无法触发碰撞检测方法 2.1.1 OnCollisionEnter、OnTriggerEnter、OnTriggerStay方法 OnCollisionEnter:检测与被检测方都应有Collider或者Rigibody,如果都有Rigibody,需勾选isKinematic。 OnTriggerEnter:检测与被检测方至少有一个Rigibody(

    2024年02月20日
    浏览(34)
  • 【Unity入门】24.碰撞检测

        大家好,我是Lampard~~     欢迎来到Unity入门系列博客,所学知识来自B站阿发老师~感谢    (1)Collider组件     上节课我们有学习到,unity的物理系统提供了更方便的碰撞检测机制,就是 提供各种的Collider组件去检测碰撞需求 Unity 中有以下几种 Collider 组件: 1. Box Coll

    2024年02月06日
    浏览(40)
  • 10.pygame碰撞检测

    Pygame中的碰撞检测功能可以用于检测两个游戏对象是否相交或重叠。这种技术非常有用,因为它可以使游戏对象之间的交互更加真实和逼真。在本教程中,我们将介绍如何使用Pygame的碰撞检测功能。 首先,我们需要导入pygame和sys模块: 然后,我们需要初始化pygame: 接下来,

    2024年02月14日
    浏览(35)
  • Unity的碰撞检测(一)

    (一)测试前准备工作         1.创建两个游戏对象,分别取名为” Player ”和” Enemy ”,并且为名为” Player ”的游戏对象设置Tag也为” Player ”,二者在场景中如图1所示: 图 1 绿为Enemy,红为Player         2.编写脚本组件” TriggerTest ”,并挂载到 Enemy 上,代码如下

    2024年02月08日
    浏览(40)
  • 碰撞检测算法详述

    算法的分类 目录 一、基于空间域的碰撞检测算法分类 1. 基于图像空间的碰撞算法 2.基于几何空间的碰撞检测算法 (1)基于空间剖分算法 (2)裁剪扫掠法 (3)基于距离场的算法 (4)基于层次包围盒的算法 ① 轴向包围盒 ② 球包围盒 ③ 方向包围盒 ④ 离散方向多面体 从

    2024年02月07日
    浏览(46)
  • 碰撞检测——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算法的比较 4.2 GJK算法和EPA算法的比较 参考资料 GJK算法是由 Gilber

    2024年02月11日
    浏览(42)
  • unity中的射线碰撞检测

    在Unity中,射线碰撞检测是一种常用的技术,通常用于确定射线与场景中的物体是否相交,并获取相交点的信息。 1.创建射线: 使用 Ray 类或 RaycastHit 结构体创建射线。 Ray 表示射线的起点和方向,而 RaycastHit 用于存储射线与物体相交的信息,如相交点、法线等。 2.发射射线:

    2024年03月17日
    浏览(42)
  • 碰撞检测算法之GJK算法

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

    2024年02月06日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包