旋转矩形碰撞检测 OBB方向包围盒算法

  在cocos2dx中进行矩形的碰撞检测时需要对旋转过的矩形做碰撞检查,由于游戏没有使用Box2D等物理引擎,所以采用了OBB(Oriented bounding box)方向包围盒算法,这个算法是基于SAT(Separating Axis Theorem)分离轴定律的。

  分离轴定律:两个凸多边形物体,如果我们能找到一个轴,使得两个在物体在该轴上的投影互不重叠,则这两个物体之间没有碰撞发生,该轴为Separating Axis。也就是说两个多边形在所有轴上的投影都发生重叠,则判定为碰撞;否则,没有发生碰撞。

  现在,我们来考虑一下矩形,矩形有4条边,那么就有4条轴,由于矩形的对边是平行的,所以有两条轴是重复的,我们仅需要检查相邻的两个轴,那么两个矩形就需要检查4个轴。

  检查投影有两种方法:第一种,把每个矩形的4个顶点投影到一个轴上,这样算出4个顶点最长的连线距离,以后同样对待第二个矩形,最后判断2个矩形投影距离是否重叠。第二种,把2个矩形的半径距离投影到轴上,以后把2个矩形的中心点连线投影到轴上,以后判断2个矩形的中心连线投影,和2个矩形的半径投影之和的大小。

  由于已经有很多文章来介绍OBB的原理,所以这里并不过多解释,我只将我实现的源码列出来仅供大家参考,代码已经经过测试,如下:

#ifndef _OBBRECT_H_
#define _OBBRECT_H_

#include <math.h>

class OBBRect {
public:
    OBBRect(float x, float y, float width, float height, float rotation = 0.0f)
        : _x(x), _y(y), _width(width), _height(height), _rotation(rotation) {
        resetVector();
    }

    bool intersects(OBBRect& other) {
        float distanceVector[2] = {
            other._x - _x,
            other._y - _y
        };

        for (int i = 0; i < 2; ++i) {
            if (getProjectionRadius(_vectors[i]) + other.getProjectionRadius(_vectors[i])
                <= dot(distanceVector, _vectors[i])) {
                return false;
            }
            if (getProjectionRadius(other._vectors[i]) + other.getProjectionRadius(other._vectors[i])
                <= dot(distanceVector, other._vectors[i])) {
                return false;
            }
        }

        return true;
    }

private:
    void resetVector() {
        _vectors[0][0] = cos(_rotation);
        _vectors[0][1] = sin(_rotation);
        _vectors[1][0] = -_vectors[0][1];
        _vectors[1][1] = _vectors[0][0];
    }

    float dot(float a[2], float b[2]) {
        return abs(a[0] * b[0] + a[1] * b[1]);
    }

    float getProjectionRadius(float vector[2]) {
        return (_width * dot(_vectors[0], vector) / 2
            + _height * dot(_vectors[1], vector) / 2);
    }

    float _x;
    float _y;
    float _width;
    float _height;
    float _rotation;
    float _vectors[2][2];
};

#endif // _OBBRECT_H_
时间: 2024-10-06 12:19:56

旋转矩形碰撞检测 OBB方向包围盒算法的相关文章

矩形旋转碰撞,OBB方向包围盒算法实现

如何进行2D旋转矩形的碰撞检测,可以使用一种叫OBB的检测算法(Oriented bounding box)方向包围盒.这个算法是基于SAT(Separating Axis Theorem)分离轴定律的.而OBB不仅仅是计算矩形的碰撞检测,而是一种算法模型.简单解释一下概念,包围盒和分离轴定律. 包围盒:是根据物体的集合形状,来决定盒子的大小和方向,这样可以选择最紧凑的盒子来代表物体.见下图 黑色的就是包围盒,可以是凸多边形,最贴近检测物体即可. 分离轴定律:两个凸多边形物体,如果我们能找到一个

【COCOS2DX-游戏开发之三六】圆与未旋转矩形的碰撞检测(上篇)

我们以cocos2dx lua脚本来说明,原理才是重点 检测圆和矩形碰撞,首先要找到矩形上离圆的中心点最近的点 if circle.x < box.x then cx = box.x end 如果圆在矩形的左边,离着圆中心点最近的矩形上的点在矩形的左边边界上 elseif circle.x > box.x + box.width then cx = box.x + box.width 如果圆的中心点在矩形的右边,离着圆中心点最近的矩形上的点在矩形的右边边界上 else cx = circle.

圆与矩形碰撞检测

圆与矩形的碰撞检测,假设矩形中心点v0, 上边中心点v1, 右边中心点v2, 圆心v, 圆半径r, 矩形半宽w1, 矩形半高h1,.v0为矩形的坐标系原点,(v0,v2)为矩形坐标系x轴,(v0,v1)为矩形坐标系y轴,圆心到矩形y轴距离为w2, 圆心到矩形x轴距离为h2,如图所示: 根据图示可以很容易的写出圆与矩形的碰撞检测算法: 圆与矩形碰撞检测

html --- VML --- javascript --- 旋转矩形

矢量标记语言 --- Vector Markup Language 运行它的代码需要打开IE的兼容性视图 如有疑问请参考:http://msdn.microsoft.com/en-us/library/bb264280(VS.85).aspx 代码如下: <html xmlns:v="urn:schemas-microsoft-com:vml"> <head> <!-- VML requires VML namespace and behavior. --

矩形碰撞检测和圆形碰撞检测。

矩形碰撞检测: <!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title><style type="text/css">body { margin: 0;}#wrap { margin: 50px auto; position: relative; borde

POJ 2187 旋转卡壳 + 水平序 Graham 扫描算法

水平序 Graham 扫描算法: 计算二维凸包的时候可以用到,Graham 扫描算法有水平序和极角序两种. 极角序算法能一次确定整个凸包, 但是计算极角需要用到三角函数,速度较慢,精度较差,特殊情况较多. 水平序算法需要扫描两次,但排序简单,讨论简单,不易出错. [算法流程] 1.对顶点按x为第一关键字,y为第二关键字进行排序. 2.准备一个空栈,并将前两个点压入栈. 3.对于每一个顶点A,只要栈顶中还至少两个顶点,记栈顶为T,栈中第二个为U. 若UT(向量) * TA(向量) <= 0, 则将

UIPanGestureRecognizer上下左右滑动方向判断算法

CGFloat const gestureMinimumTranslation = 20.0; typedef enum :NSInteger { kCameraMoveDirectionNone, kCameraMoveDirectionUp, kCameraMoveDirectionDown, kCameraMoveDirectionRight, kCameraMoveDirectionLeft } CameraMoveDirection; @interfaceViewController

碰撞检测之分离轴定理算法讲解

本文翻译自@sevenson的文章Separating Axis Theorem (SAT) Explanation .原文作者用的是ActionScript 3来编写算法,不过文中主要讲述的还是算法原理,我想一旦算法原理被我们掌握了,选择什么编程语言来实现算法都是次要的事情了. 本人并非英文专业,所以文中翻译得有不妥或疏漏之处,欢迎各位指正,谢谢! 正文如下: 分离轴定理(英文简称SAT)是一项用于检测凸多边形碰撞的技术. 我绝不是这个方面的专家,但当检测碰撞的需求出现在我面前之后,我做了大量

【iOS】屏幕旋转,屏幕自适应方向变化

1. iOS有四个方向的旋转,为了保证自己的代码能够支持旋转,我们必须首先处理一个函数: Objective-c代码   - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { return YES; } 2. 这个函数时用来确定我们的应用所支持的旋转方向.如果想要支持每个方向则直接返回YES就行,还可以单独判断某一方向: Objective-c代码   - (BO