热门标签 | 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手工解析像素。

推荐阅读
  • 深入理解OAuth认证机制
    本文介绍了OAuth认证协议的核心概念及其工作原理。OAuth是一种开放标准,旨在为第三方应用提供安全的用户资源访问授权,同时确保用户的账户信息(如用户名和密码)不会暴露给第三方。 ... [详细]
  • 1:有如下一段程序:packagea.b.c;publicclassTest{privatestaticinti0;publicintgetNext(){return ... [详细]
  • c# – UWP:BrightnessOverride StartOverride逻辑 ... [详细]
  • 本文探讨了如何在给定整数N的情况下,找到两个不同的整数a和b,使得它们的和最大,并且满足特定的数学条件。 ... [详细]
  • 本文深入探讨了 Java 编程语言的基础,特别是其跨平台特性和 JVM 的工作原理。通过介绍 Java 的发展历史和生态系统,帮助初学者理解如何编写并运行第一个 Java 程序。 ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
  • 本文介绍了如何在C#应用程序中有效隐藏SQLCMD命令行窗口,确保程序运行时不会弹出黑色命令提示符窗口。 ... [详细]
  • Ihaveastringwithquotesaroundthepathasfollows:我在路径周围有一个带引号的字符串,如下所示:C:\ProgramFiles(x ... [详细]
  • 本文探讨了使用C#在SQL Server和Access数据库中批量插入多条数据的性能差异。通过具体代码示例,详细分析了两种数据库的执行效率,并提供了优化建议。 ... [详细]
  • 本文详细介绍了IBM DB2数据库在大型应用系统中的应用,强调其卓越的可扩展性和多环境支持能力。文章深入分析了DB2在数据利用性、完整性、安全性和恢复性方面的优势,并提供了优化建议以提升其在不同规模应用程序中的表现。 ... [详细]
  • QUIC协议:快速UDP互联网连接
    QUIC(Quick UDP Internet Connections)是谷歌开发的一种旨在提高网络性能和安全性的传输层协议。它基于UDP,并结合了TLS级别的安全性,提供了更高效、更可靠的互联网通信方式。 ... [详细]
  • 国内BI工具迎战国际巨头Tableau,稳步崛起
    尽管商业智能(BI)工具在中国的普及程度尚不及国际市场,但近年来,随着本土企业的持续创新和市场推广,国内主流BI工具正逐渐崭露头角。面对国际品牌如Tableau的强大竞争,国内BI工具通过不断优化产品和技术,赢得了越来越多用户的认可。 ... [详细]
  • 本文详细介绍了如何在C#程序运行期间防止系统进入休眠模式以及显示器关闭,提供了具体的实现代码示例,并解释了其应用场景。这不仅有助于提高程序的稳定性,还能优化能源管理。适合需要处理长时间任务(如下载或批处理)的开发者参考。 ... [详细]
  • Python处理Word文档的高效技巧
    本文详细介绍了如何使用Python处理Word文档,涵盖从基础操作到高级功能的各种技巧。我们将探讨如何生成文档、定义样式、提取表格数据以及处理超链接和图片等内容。 ... [详细]
  • 编写了几个500行左右代码的程序,但基本上解决问题还是面向过程的思维,如何从问题中抽象出类,形成类的划分和设计,从而用面向对象的思维解决问题?有这方面的入门好书吗?最好是结合几个具体的案例分析的 ... [详细]
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社区 版权所有