之前发的小游戏滚蛋躲方块中,用它来判断球体与立方体是否发生了碰撞.

http://www.cnblogs.com/WhyEngine/p/3350012.html

现在发布下该算法:

有向包围盒OBB,是有旋转变化的包围盒,由三种数据组成:

obbCenter表示包围盒的中心位置

obbAxes[3]表示包围盒XYZ三个坐标轴方向上的朝向,应该是正交的,否则意思着立方体有扭曲变形.并且应该是单位向量.

halfExtents表示包围盒三个方向上的长度.

该算法是多年前,已经不记得从什么地方找的了,自己又做了点修改.该代码其实可以更加简化一些,因为原代码中是可以计算球与包围盒的碰撞深度与碰撞的法线方向的.而这里只需要返回TRUE或FALSE即可.

算法的原理比较容易理解:判断球心到包围盒三个坐标轴的投影距离是否小于该轴的长度加上球的半径.如果三个轴都符合,则表示有碰撞.

该算法的基础是判断空间中一点是否在包围盒内部.

 bool ObbSphereCollisionDetect(const Vector3& obbCenter,
const Vector3 obbAxes[],
const Vector3& halfExtents,
const Vector3& sphereCenter,
float sphereRadius)
{
Vector3 kDiff = sphereCenter - obbCenter; float fSide[] = { 1.0f, 1.0f, 1.0f };
float fS[] = { 0.0f, 0.0f, 0.0f };
float fD = 0.0f; if (D3DXVec3Dot(&kDiff, &obbAxes[]) < 0.0f)
{
fS[] = D3DXVec3Dot(&( sphereCenter - ( obbCenter - ( obbAxes[] * halfExtents.x ) ) ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
}
else
{
fS[] = D3DXVec3Dot(&( ( obbCenter + ( obbAxes[] * halfExtents.x ) ) - sphereCenter ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
fSide[] = -1.0f;
} if (D3DXVec3Dot(&kDiff, &obbAxes[]) < 0.0f)
{
fS[] = D3DXVec3Dot(&( sphereCenter - ( obbCenter - ( obbAxes[] * halfExtents.y ) ) ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
}
else
{
fS[] = D3DXVec3Dot(&( ( obbCenter + ( obbAxes[] * halfExtents.y ) ) - sphereCenter ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
fSide[] = -1.0f;
} if (D3DXVec3Dot(&kDiff, &obbAxes[]) < 0.0f)
{
fS[] = D3DXVec3Dot(&( sphereCenter - ( obbCenter - ( obbAxes[] * halfExtents.z ) ) ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
}
else
{
fS[] = D3DXVec3Dot(&( ( obbCenter + ( obbAxes[] * halfExtents.z ) ) - sphereCenter ), &obbAxes[]); if (fS[] <= -sphereRadius)
return false; else if (fS[] < 0.0f)
fD += fS[] * fS[]; fS[] += sphereRadius;
fSide[] = -1.0f;
} return (fD <= ( sphereRadius * sphereRadius ));
}

3D有向包围盒与球体碰撞的算法的更多相关文章

  1. 碰撞回避算法(一) Velocity Obstacle

    碰撞回避是机器人导航,游戏AI等领域的基础课题.几十年来,有很多算法被提出.注意这里主要指的是局部的碰撞回避算法.尽管和全局的路径规划算法(A*算法等)有千丝万缕的联系.可是还是有所不同的(局部的碰撞 ...

  2. 3D空间中射线与轴向包围盒AABB的交叉检测算法【转】

    引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法.但是,我们应该知道,在游戏开发中,一个模型有很多的三角形构成,如果要对所有的物体,所有的三角形进行这种检测,就算现在的计算机运算能力,也是 ...

  3. 3D空间中射线与轴向包围盒AABB的交叉检测算法 【转】

    http://blog.csdn.net/i_dovelemon/article/details/38342739 引言 在上一节中,我讲述了如何实现射线与三角形的交叉检测算法. 但是,我们应该知道, ...

  4. 游戏碰撞OBB算法(java代码)

    业务需求      游戏2D型号有圆形和矩形,推断说白了就是碰撞检测 :      1.圆形跟圆形是否有相交      2.圆形跟矩形是否相交       3.矩形和矩形是否相交           ...

  5. 【Unity 3D】学习笔记三十七:物理引擎——碰撞与休眠

    碰撞与休眠 上一篇笔记说过,当给予游戏对象刚体这个组件以后,那么这个组件将存在碰撞的可能性.一旦刚体開始运动,那么系统方法便会监视刚体的碰撞状态.一般刚体的碰撞分为三种:进入碰撞,碰撞中,和碰撞结束. ...

  6. 数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇

    <数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT ...

  7. 【翻译】西川善司的「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,后篇

    http://www.4gamer.net/games/216/G021678/20140714079/     连载第2回的本回,  Arc System Works开发的格斗游戏「GUILTY G ...

  8. 利用Flare3D和Stage3D创建3D

    Flare3D 是一款功能强大的引擎,它使得 Flash 中的 3D 内容管理变得更为简便. 它的设计宗旨是提供一个完美的开发工作流程,以便你能够获得事半功倍的效果. 本教程侧重讨论在 Flash 中 ...

  9. 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门示例

    一. 工作区域详解 1. Scence视图 (场景设计面板) scence视图简介 : 展示创建的游戏对象, 可以对所有的游戏对象进行 移动, 操作 和 放置; -- 示例 : 创建一个球体, 控制摄 ...

随机推荐

  1. mysql 存储过程详解

    MySQL 存储过程是从 MySQL 5.0 开始增加的新功能.存储过程的优点有一箩筐.不过最主要的还是执行效率和SQL 代码封装.特别是 SQL 代码封装功能,如果没有存储过程,在外部程序访问数据库 ...

  2. Hadoop CapacitySchedule配置

    下面是Hadoop中CapacitySchedule配置,包含了新建队列和子队列 <configuration> <property> <name>yarn.sch ...

  3. [CodeForces - 678F] Lena and Queries 线段树维护凸包

    大致题意: 给出三种操作 1.往平面点集中添加一个点 2.删除第i次添加的点 3.给出一个q,询问平面点集中的q*x+y的最大值 首先对于每个询问,可将z=q*x+y转化为y=z-q*x,即过点(x, ...

  4. 2016-2017 ACM-ICPC Pacific Northwest Regional Contest (Div. 2) 题解

    [题目链接] A - Alphabet 最长公共子序列.保留最长公共子序列,剩余的删除或者补足即可. #include <bits/stdc++.h> using namespace st ...

  5. 六、django rest_framework源码之解析器剖析

    1 绪论 网络传输数据只能传输字符串格式的,如果是列表.字典等数据类型,需要转换之后才能使用但是我们之前的rest_framework例子都没有转换就直接可以使用了,这是因为rest_framewor ...

  6. tomcat如何利用waf进行防护

    近期某一实验室遇到一个问题:web环境是windows+tomcat+mysql,检测到cookie注入,此时又不想修改代码.此时两种方案进行解决: 1.利用安软(waf)类进行检测防御.这里国内主要 ...

  7. 获取Android apk的包名

    Read the package name of an Android APK aapt dump badging <path-to-apk> | grep package:\ name

  8. Ubuntu 16.04 64位 tftp服务器搭建

    TFTP(Trivial File Transfer Protocol,简单文件传输协议)是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂.开销不大的文件传输服务 ...

  9. wpf企业应用之带选项框的TreeView

    wpf里面实现层次绑定主要使用HierarchicalDataTemplate,这里主要谈一谈带checkbox的treeview,具体效果见 wpf企业级开发中的几种常见业务场景. 先来看一下我的控 ...

  10. vijos p1881 线段树

    题意:点我 我就想问,现在换代码风格还来得及吗? 2015-05-19:线段树进一步加强,看来不用换风格了 维护左右节点左右端颜色和长度即可 #include<cstdio> #inclu ...