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

推荐阅读
  • 本文档介绍了如何在Visual Studio 2010环境下,利用C#语言连接SQL Server 2008数据库,并实现基本的数据操作,如增删改查等功能。通过构建一个面向对象的数据库工具类,简化了数据库操作流程。 ... [详细]
  • 在尝试使用C# Windows Forms客户端通过SignalR连接到ASP.NET服务器时,遇到了内部服务器错误(500)。本文将详细探讨问题的原因及解决方案。 ... [详细]
  • 本文介绍了如何在 C# 和 XNA 框架中实现一个自定义的 3x3 矩阵类(MMatrix33),旨在深入理解矩阵运算及其应用场景。该类参考了 AS3 Starling 和其他相关资源,以确保算法的准确性和高效性。 ... [详细]
  • 本文介绍了解决在Windows操作系统或SQL Server Management Studio (SSMS) 中遇到的“microsoft.ACE.oledb.12.0”提供程序未注册问题的方法,特别针对Access Database Engine组件的安装。 ... [详细]
  • 深入理解Java多线程并发处理:基础与实践
    本文探讨了Java中的多线程并发处理机制,从基本概念到实际应用,帮助读者全面理解并掌握多线程编程技巧。通过实例解析和理论阐述,确保初学者也能轻松入门。 ... [详细]
  • 本文详细介绍了如何解决 Microsoft SQL Server 中用户 'sa' 登录失败的问题。错误代码为 18470,提示该帐户已被禁用。我们将通过 Windows 身份验证方式登录,并启用 'sa' 帐户以恢复其访问权限。 ... [详细]
  • 深入剖析JVM垃圾回收机制
    本文详细探讨了Java虚拟机(JVM)中的垃圾回收机制,包括其意义、对象判定方法、引用类型、常见垃圾收集算法以及各种垃圾收集器的特点和工作原理。通过理解这些内容,开发人员可以更好地优化内存管理和程序性能。 ... [详细]
  • 远程过程调用(RPC)是一种允许客户端通过网络请求服务器执行特定功能的技术。它简化了分布式系统的交互,使开发者可以像调用本地函数一样调用远程服务,并获得返回结果。本文将深入探讨RPC的工作原理、发展历程及其在现代技术中的应用。 ... [详细]
  • 本文针对Windows 7环境下使用IIS 7.5和.NET Framework 4.0时遇到的ASP.NET设置不适用于集成托管管道模式的问题,提供了一个有效的解决方案。通过调整web.config文件中的特定配置,可以轻松解决此问题。 ... [详细]
  • Microsoft即将发布WPF/E的CTP(Community Technology Preview)和SDK,标志着RIA(Rich Internet Application)技术的新里程碑。更多详情及下载链接请参见MSDN官方页面。 ... [详细]
  • 本文探讨了如何解决PHP文件无法写入本地文件的问题,并解释了PHP文件中HTML代码无效的原因,提供了一系列实用的解决方案和最佳实践。 ... [详细]
  • 鼠标悬停出现提示信息怎么做
    概述–提示:指启示,提起注意或给予提醒和解释。在excel中会经常用到给某个格子增加提醒信息,比如金额提示输入数值或最大长度值等等。设置方式也有多种,简单的,仅为单元格插入批注就可 ... [详细]
  • 本文详细探讨了如何通过分析单个或多个线程在瓶颈情况下的表现,来了解处理器资源的消耗。无论是单进程还是多进程环境,监控关键指标如线程数量、占用时间及调度优先级等,有助于揭示潜在的性能问题。 ... [详细]
  • Python Django大学生心理健康管理系统开发(含源码、文档)
    本项目包含完整的源代码、设计文档、数据库结构以及详细的安装指南,旨在为计算机专业的学生提供一个全面的心理健康管理系统解决方案。 ... [详细]
  • 气象对比分析
    本文探讨了不同地区和时间段的天气模式,通过详细的图表和数据分析,揭示了气候变化的趋势及其对环境和社会的影响。 ... [详细]
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社区 版权所有