热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

建立2DAABB

AABB是游戏中经常用的包围盒。本文提出一种2D空间内自动生成AABB的算法,读者也可在此基础上开发出基于3D的AABB自动生成算法。本算法可以用来在一个给定区域内进行AABB的自动挖掘产生。如:场景内各建筑的阻挡点包围框;纹理贴图上小图标的包围框……算法

AABB是游戏中经常用的包围盒。本文提出一种2D空间内自动生成AABB的算法,读者也可在此基础上开发出基于3D的AABB自动生成算法。 本算法可以用来在一个给定区域内进行AABB的自动挖掘产生。如:场景内各建筑的阻挡点包围框;纹理贴图上小图标的包围框…… 算法

AABB是游戏中经常用的包围盒。本文提出一种2D空间内自动生成AABB的算法,读者也可在此基础上开发出基于3D的AABB自动生成算法。

本算法可以用来在一个给定区域内进行AABB的自动挖掘产生。如:场景内各建筑的阻挡点包围框;纹理贴图上小图标的包围框……

算法描述:

  1. 创建一个AABB空列表aabbList
  2. 循环给定空间内的每一个点pt
  3. 如果pt为不感兴趣的点,则跳转2
  4. 如果pt为感兴趣的点
  5. 为pt创建一个大小为1的AABB rect
  6. 遍历aabbList中每个元素aabb
  7. 如果rect和aabb邻接或相交,则表明rect和aabb可以合并
  8. rect = Union(rect,aabb),将aabb合并到rect
  9. 从aabbList中删除aabb
  10. 将rect加入到aabbList
  11. 返回aabbList

C#实现代码如下:

///

/// 判断是否对给定位置感兴趣并愿意放入AABB

///

delegate bool InterestPredicate(int x, int y);

///

/// 得到给定区域范围内的所有AABB

///

/// 要搜索的区域,该区域的每个点值将逐一传给

static List<Rectangle> GenerateAllAABB(Rectangle area, InterestPredicate isInterest)

{

if (isInterest == null)

throw new ArgumentNullException("isEmpty");

// 结果包围框集

List<Rectangle> aabbList = new List<Rectangle>();

// 临时变量。一次合并过程中发现的可合并的包围框下标

List<int> intersectList = new List<int>();

for (int y = area.Top; y

{

for (int x = area.Left; x

{

if (isInterest(x, y) == false)

continue;

intersectList.Clear();

Rectangle rect = new Rectangle(x, y, 1, 1);

// 对已有的包围框进行遍历合并

for (int i = 0; i

{

Rectangle aabb = aabbList[i];

// 判断是否邻接,相交或者紧挨着都算邻接

if (rect.IntersectsWith(new Rectangle(aabb.X - 1, aabb.Y - 1, aabb.Width &#43; 2, aabb.Height &#43; 2)))

{

rect = Rectangle.Union(rect, aabb);

intersectList.Add(i);

}

}

// 倒序遍历,避免对list进行删除时下标失效

for (int i = intersectList.Count - 1; i >= 0; i--)

{

aabbList.RemoveAt(intersectList[i]);

}

// 将合并后的包围框加入结果集

aabbList.Add(rect);

}

}

return aabbList;

}

下面的例子给CEGUI WindowsLook风&#26684;的贴图加上AABB包围框,该工作如果用CEImagesetEditor之类的工具手工做的话需要很长的时间和耐心。

private void Form1_Load(object sender, EventArgs e)

{

int backgroundColor = Color.White.ToArgb();

Bitmap bitmap = new Bitmap("WindowsLook.bmp");

// 计算包围框

List<Rectangle> list = GenerateAllAABB(

new Rectangle(0, 0, bitmap.Width, bitmap.Height),

(x, y) =>

{

Color c = bitmap.GetPixel(x, y);

return c.A != 0 && c.ToArgb() != backgroundColor;

});

// 将得到的包围框绘制出来

using (Graphics g = Graphics.FromImage(bitmap))

{

Pen pen = new Pen(Color.FromArgb(100, Color.Red));

g.DrawRectangles(pen, list.ToArray());

pen.Dispose();

}

pictureBox1.Image = bitmap;

}

结果为下图中右边的样子,左边是原始的图片:

可以考虑将该算法加入到CEImagesetEditor工具中,对新建立的Imageset,自动生成小图标的包围盒。在此基础上手工稍作调整即可。

感谢廖鑫炜、开平等人提供帮助!

扩展阅读:

《数据聚类》算法(英文版的更全面)


2012-2-6

若性能不满足,可以用Bitmap.LockBits替代Bitmap.GetPixel手工解析像素。

推荐阅读
  • 使用C#构建动态图形界面时钟
    本篇文章将详细介绍如何利用C#语言开发一个具有动态显示功能的图形界面时钟。文章中不仅提供了详细的代码示例,还对可能出现的问题进行了深入分析,并给出了解决方案。 ... [详细]
  • 对于初学者而言,搭建一个高效稳定的 Python 开发环境是入门的关键一步。本文将详细介绍如何利用 Anaconda 和 Jupyter Notebook 来构建一个既易于管理又功能强大的开发环境。 ... [详细]
  • 我的读书清单(持续更新)201705311.《一千零一夜》2006(四五年级)2.《中华上下五千年》2008(初一)3.《鲁滨孙漂流记》2008(初二)4.《钢铁是怎样炼成的》20 ... [详细]
  • 在OpenCV 3.1.0中实现SIFT与SURF特征检测
    本文介绍如何在OpenCV 3.1.0版本中通过Python 2.7环境使用SIFT和SURF算法进行图像特征点检测。由于这些高级功能在OpenCV 3.0.0及更高版本中被移至额外的contrib模块,因此需要特别处理才能正常使用。 ... [详细]
  • Windows操作系统提供了Encrypting File System (EFS)作为内置的数据加密工具,特别适用于对NTFS分区上的文件和文件夹进行加密处理。本文将详细介绍如何使用EFS加密文件夹,以及加密过程中的注意事项。 ... [详细]
  • 深入解析层次聚类算法
    本文详细介绍了层次聚类算法的基本原理,包括其通过构建层次结构来分类样本的特点,以及自底向上(凝聚)和自顶向下(分裂)两种主要的聚类策略。文章还探讨了不同距离度量方法对聚类效果的影响,并提供了具体的参数设置指导。 ... [详细]
  • 本文介绍了如何在不同操作系统上安装Git,以及一些基本和高级的Git操作,包括项目初始化、文件状态检查、版本控制、分支管理、标签处理、版本回退等,并简要提及了开源许可协议的选择。 ... [详细]
  • C#中调用OpenCTM打开.obj三维模型文件
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • pypy 真的能让 Python 比 C 还快么?
    作者:肖恩顿来源:游戏不存在最近“pypy为什么能让python比c还快”刷屏了,原文讲的内容偏理论,干货比较少。我们可以再深入一点点,了解pypy的真相。正式开始之前,多唠叨两句 ... [详细]
  • NPM 脚本 'start' 退出,未显示 create-react-app 服务器正在监听请求
    遇到 NPM 脚本 'start' 退出且未显示 create-react-app 服务器正在监听请求的问题,请求帮助。 ... [详细]
  • 本文详细介绍了如何对一个整数的二进制表示进行逆序操作。通过多种方法,包括直接法、查表法和分治法,帮助读者全面理解和掌握这一技术。 ... [详细]
  • 本文将详细探讨PHP中C的作用,并对比其他编程语言如Java和C的特点及其适用场景。 ... [详细]
  • 优先队列是一种特殊的队列,不遵循先进先出原则。它分为最大优先队列和最小优先队列。最大优先队列总是将当前最大的元素优先出队,而最小优先队列则总是将当前最小的元素优先出队。本文将详细介绍如何使用二叉堆在C#中实现这两种优先队列。 ... [详细]
  • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
  • 一款名为Zeno的家庭机器人已经开发完成,灵感源自于日本动漫《铁臂阿童木》中的角色。该机器人能够行走、交流,并通过面部表情传达情感。 ... [详细]
author-avatar
丿氵小柒柒2502894463
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有