【运动规划算法项目实战】如何利用AABB作碰撞检测(附ROS C++代码)


前言

AABB碰撞检测是一种基于包围盒的简单、快速和有效的碰撞检测方法,被广泛应用于各种计算机图形学和物理仿真系统中。其基本思想是将物体或场景中的复杂几何形状简化为简单的矩形包围盒,然后判断两个包围盒之间是否存在重叠,以确定它们是否碰撞。AABB碰撞检测之所以受到广泛关注,是因为它既可以快速检测复杂物体之间的碰撞,又可以减少计算量和内存占用,适用于实时应用和大规模场景。

AABB包围盒是一种简单、轴对齐和矩形的几何形状,通常由一个最小点和一个最大点确定。它的特点是轴对齐,即包围盒的边缘与坐标轴平行,便于计算和比较;矩形形状使得其在平面和立体场景中都适用。AABB碰撞检测一般用作粗略检测,使用简单的AABB包围盒来检测碰撞,用作快速剔除不可能碰撞的对象。更进一步精确检测则需要使用更高级的算法,例如分离轴定理(Separating Axis Theorem,SAT)才能做出更准确地判断碰撞。

本篇文章旨在帮助读者了解AABB碰撞检测的基础知识、应用场景、碰撞检测流程以及如何实现和优化AABB碰撞检测算法。
在这里插入图片描述


一、包围盒(Bounding Box)简介

包围盒(Bounding Box)是指能够紧密围绕一个物体或场景的最小的矩形或立方体边界框,通常用于几何形状的简化

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是一个带 AABB 的 Octree 算法的 C 实现的碰撞检测代码: ```c #include <stdio.h> #include <stdlib.h> #define MAX_DEPTH 8 #define MAX_OBJECTS 10 typedef struct { float x, y, z; } Vector3; typedef struct { Vector3 min, max; } AABB; typedef struct { AABB bounds; int object_id; } OctreeObject; typedef struct OctreeNode OctreeNode; struct OctreeNode { AABB bounds; OctreeNode* children[8]; OctreeObject* objects[MAX_OBJECTS]; int num_objects; int depth; }; OctreeNode* create_node(AABB bounds, int depth) { OctreeNode* node = (OctreeNode*)malloc(sizeof(OctreeNode)); node->bounds = bounds; for (int i = 0; i < 8; i++) { node->children[i] = NULL; } for (int i = 0; i < MAX_OBJECTS; i++) { node->objects[i] = NULL; } node->num_objects = 0; node->depth = depth; return node; } void insert_object(OctreeNode* node, OctreeObject* object) { if (node->children[0] != NULL) { // Node has children, insert object into appropriate child for (int i = 0; i < 8; i++) { if (AABB_intersects(node->children[i]->bounds, object->bounds)) { insert_object(node->children[i], object); return; } } } // Node does not have children, insert object into this node if (node->num_objects < MAX_OBJECTS || node->depth >= MAX_DEPTH) { node->objects[node->num_objects++] = object; } else { // Node is full, split it into eight children Vector3 center = { (node->bounds.min.x + node->bounds.max.x) / 2, (node->bounds.min.y + node->bounds.max.y) / 2, (node->bounds.min.z + node->bounds.max.z) / 2 }; node->children[0] = create_node((AABB){node->bounds.min, center}, node->depth + 1); node->children[1] = create_node((AABB){(Vector3){center.x, node->bounds.min.y, node->bounds.min.z}, (Vector3){node->bounds.max.x, center.y, center.z}}, node->depth + 1); node->children[2] = create_node((AABB){(Vector3){center.x, node->bounds.min.y, center.z}, (Vector3){node->bounds.max.x, center.y, node->bounds.max.z}}, node->depth + 1); node->children[3] = create_node((AABB){(Vector3){node->bounds.min.x, node->bounds.min.y, center.z}, (Vector3){center.x, center.y, node->bounds.max.z}}, node->depth + 1); node->children[4] = create_node((AABB){(Vector3){node->bounds.min.x, center.y, node->bounds.min.z}, (Vector3){center.x, node->bounds.max.y, center.z}}, node->depth + 1); node->children[5] = create_node((AABB){(Vector3){center.x, center.y, node->bounds.min.z}, (Vector3){node->bounds.max.x, node->bounds.max.y, center.z}}, node->depth + 1); node->children[6] = create_node((AABB){(Vector3){center.x, center.y, center.z}, node->bounds.max}, node->depth + 1); node->children[7] = create_node((AABB){(Vector3){node->bounds.min.x, center.y, center.z}, (Vector3){center.x, node->bounds.max.y, node->bounds.max.z}}, node->depth + 1); for (int i = 0; i < node->num_objects; i++) { for (int j = 0; j < 8; j++) { if (AABB_intersects(node->children[j]->bounds, node->objects[i]->bounds)) { insert_object(node->children[j], node->objects[i]); node->objects[i] = NULL; break; } } } for (int i = 0; i < node->num_objects; i++) { if (node->objects[i] != NULL) { insert_object(node, node->objects[i]); node->objects[i] = NULL; } } insert_object(node, object); } } int AABB_intersects(AABB a, AABB b) { return (a.min.x <= b.max.x && a.max.x >= b.min.x) && (a.min.y <= b.max.y && a.max.y >= b.min.y) && (a.min.z <= b.max.z && a.max.z >= b.min.z); } void query_objects(OctreeNode* node, AABB bounds, int* results, int* num_results) { if (!AABB_intersects(node->bounds, bounds)) { return; } for (int i = 0; i < node->num_objects; i++) { if (AABB_intersects(node->objects[i]->bounds, bounds)) { results[(*num_results)++] = node->objects[i]->object_id; } } if (node->children[0] != NULL) { for (int i = 0; i < 8; i++) { query_objects(node->children[i], bounds, results, num_results); } } } int main() { // Example usage OctreeNode* root = create_node((AABB){(Vector3){-10, -10, -10}, (Vector3){10, 10, 10}}, 0); OctreeObject objects[5] = { {(AABB){(Vector3){-5, -5, -5}, (Vector3){-3, -3, -3}}, 0}, {(AABB){(Vector3){-2, -2, -2}, (Vector3){0, 0, 0}}, 1}, {(AABB){(Vector3){1, 1, 1}, (Vector3){3, 3, 3}}, 2}, {(AABB){(Vector3){4, 4, 4}, (Vector3){6, 6, 6}}, 3}, {(AABB){(Vector3){7, 7, 7}, (Vector3){9, 9, 9}}, 4} }; for (int i = 0; i < 5; i++) { insert_object(root, &objects[i]); } int results[5]; int num_results = 0; query_objects(root, (AABB){(Vector3){-4, -4, -4}, (Vector3){4, 4, 4}}, results, &num_results); printf("Objects in query bounds: "); for (int i = 0; i < num_results; i++) { printf("%d ", results[i]); } printf("\n"); return 0; } ``` 希望这个代码能够帮到你!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Travis.X

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值