﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-勤能补拙-随笔分类-Ai</title><link>http://www.cppblog.com/expter/category/12025.html</link><description>成都游戏Coder，记录游戏开发过程的笔记和心得！</description><language>zh-cn</language><lastBuildDate>Thu, 24 Feb 2011 17:03:37 GMT</lastBuildDate><pubDate>Thu, 24 Feb 2011 17:03:37 GMT</pubDate><ttl>60</ttl><item><title>一个基于足球AI仿真机的模拟实现</title><link>http://www.cppblog.com/expter/archive/2010/06/30/119019.html</link><dc:creator>expter</dc:creator><author>expter</author><pubDate>Wed, 30 Jun 2010 15:36:00 GMT</pubDate><guid>http://www.cppblog.com/expter/archive/2010/06/30/119019.html</guid><wfw:comment>http://www.cppblog.com/expter/comments/119019.html</wfw:comment><comments>http://www.cppblog.com/expter/archive/2010/06/30/119019.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cppblog.com/expter/comments/commentRss/119019.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/expter/services/trackbacks/119019.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; author:expter<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; date&nbsp;&nbsp; 2010/06/30<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 介绍:&nbsp; 世界杯现在如此的备受瞩目和关注，本文介绍如何实现一个基于足球AI的实现，而作为程序员我们关注的不是目标用其赢得世界杯，而是创造一个把球踢好的智能体，加上最近上班轻松，晚上较闲，加上去年实现的一个AI模型与平时写的游戏智能算法，想组织起来完成一个足球模拟玩玩。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 本文会首先介绍一种基于AI仿真机的实现流程图，后面我将会用大量的篇幅详细介绍各个实现细节，与具体足球战术，此足球AI主要是主动攻击性AI，所以还需要具体完善加强防御性的AI,所以具体代码现在将不会现在放出。以后实现完整过后会完整公开，现在主要设计描述如下。<br>&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 足球的游戏规则不是很复杂，就是2个球队，然后每个球队一个守门员与几名球员，目的就是踢进对方的球门。简单的足球是没有傻子的，也就没有犯规，越位，头球，点球以及乌龙球。以后可能会增加上面几种。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一个简单的游戏的具体环境如下:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.一个足球场(FootBallPitch)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.一个足球&nbsp;&nbsp;&nbsp;&nbsp; FootBall<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.二个球门&nbsp;&nbsp;&nbsp;&nbsp; Goal<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.二个球队&nbsp;&nbsp;&nbsp;&nbsp; FootBallTeam<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.场上12名足球队员（每队6名，期中5名为球员2名后卫3名前锋，还有1名守门员）<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.球员&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FootBaller&nbsp;&nbsp;&nbsp; 守门员&nbsp; GoalKeeper<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp; 然后只要理清上面的描述然后把具体的实现封装到每个类中，就实现了1个简单的足球仿真模拟，实现上面的功能代码还是简单，但是如何组织强大攻击性强大，防御性强的AI还是挺复杂的。<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面将给出具体ＵＭＬ实现类图：&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <img height=612 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/ball.JPG" width=665 border=0><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于是基于智能体的足球ＡＩ所以还是借鉴了ＦＳＭ模型，我们可以把每个Player处于不同的状态进行不同的操作，具体把操作类型和事件处理都放在具体的状态中。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 基于球场上运球的FootBaller有下列状态ChaseBall 追球状态，Dribble运球&nbsp; Gohome 归位&nbsp;&nbsp; KickBall 踢球&nbsp; ReceviveBall传球&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;基于守门员GoalKeeper有InterceptBall 拦截&nbsp; PutBallBackInPlay发球.<br>&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里为了区分队员是前锋还是后卫，我们给队员增加一个行为Behaviors，让其根据自己的行为做相应的事情.。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;其中所有的图像处理都是用的GDI的绘制，程序采用的Win32编写方式。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面的设计基本是现在程序的设计方案和流程图。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后期完善部分：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.引入基于事件响应，FootBaller&nbsp;可以通知同队FootBaller&nbsp;的接收响应的消息处理，比如A发现B的位置很好，A可以通知B我要传球到一个坐标点。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.加强防御和攻击AI。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.完成具体方案后，公布所有的方案设计和具体算法，后期引入脚本机制，通过外部编写脚本实现不同队伍AI模拟。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<img src ="http://www.cppblog.com/expter/aggbug/119019.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/expter/" target="_blank">expter</a> 2010-06-30 23:36 <a href="http://www.cppblog.com/expter/archive/2010/06/30/119019.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于策略的一种高效内存池的实现</title><link>http://www.cppblog.com/expter/archive/2010/04/14/112594.html</link><dc:creator>expter</dc:creator><author>expter</author><pubDate>Wed, 14 Apr 2010 15:23:00 GMT</pubDate><guid>http://www.cppblog.com/expter/archive/2010/04/14/112594.html</guid><wfw:comment>http://www.cppblog.com/expter/comments/112594.html</wfw:comment><comments>http://www.cppblog.com/expter/archive/2010/04/14/112594.html#Feedback</comments><slash:comments>10</slash:comments><wfw:commentRss>http://www.cppblog.com/expter/comments/commentRss/112594.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/expter/services/trackbacks/112594.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一.XXX&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1)概念说明&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;这里不再具体描述内存池的概念和作用,需要了解请看http://baike.baidu.com/view/2659852.htm?fr=ala0_1_1。&nbsp;&nbsp;&nbsp;&nbs...&nbsp;&nbsp;<a href='http://www.cppblog.com/expter/archive/2010/04/14/112594.html'>阅读全文</a><img src ="http://www.cppblog.com/expter/aggbug/112594.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/expter/" target="_blank">expter</a> 2010-04-14 23:23 <a href="http://www.cppblog.com/expter/archive/2010/04/14/112594.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个小型的IOCP网络库</title><link>http://www.cppblog.com/expter/archive/2009/12/20/103566.html</link><dc:creator>expter</dc:creator><author>expter</author><pubDate>Sun, 20 Dec 2009 06:21:00 GMT</pubDate><guid>http://www.cppblog.com/expter/archive/2009/12/20/103566.html</guid><wfw:comment>http://www.cppblog.com/expter/comments/103566.html</wfw:comment><comments>http://www.cppblog.com/expter/archive/2009/12/20/103566.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cppblog.com/expter/comments/commentRss/103566.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/expter/services/trackbacks/103566.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;基本网络框架基于IOCP模型，这次主要在以前写的IPC通信的基础上修改，参考了当前项目网络库的设计思路。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 先介绍几个主要的类:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.CSocket重新套接字，CConnection继承CSocket表示一个连接对象主要重写Recv和Send接口，以及组包过程。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.CAccept处理客户端的链接，<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.Cpacket一个消息数据包头，CMessage继承CPacket带数据消息包。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.CConnectManger保存一个连接CConnection的内存池对象，CAcceptManager一个接收客户端Accept的线程，CPacketManager参考了Loki的小对象管理做的一个缓冲区数据包内存池。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5.CLibObject包含上面3个Manager(Singleton)，CNetWork网络初始化。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 6.CIOCP类主要IO的线程类，接收处理所有的客户端连接CConnection。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7.CServer类包括一个IOCP初始化和网络库管理类，IOCP会把接收到的数据重组成数据包后保存到CServer的一个CMsgQueue中.<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8.我们的重写一个Server只需要继承CServer，然后实现run和AccedeProcess即可。run从CMsgQueue缓冲区提取一个消息包，AccedeProcess处理消息。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一些细节设计:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.为了节约带宽Connection这里采用了Negles算法，这里采用Negle的并没有马上把每一个需要发送MSG采用缓存队列的方式保存起来，而是每一个Connection自身都保存数据，CServer通过一个线程把每一个存在的Connection是否有消息缓存，然后发送。因而让IOCP只处理接收的消息，发送消息通过CServer来处理。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;出网络库基本框架如下:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img height=619 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/NetLib.jpg" width=812 border=0>&nbsp; <br><br>网络库代码的代码<a href="http://code.google.com/p/tpgame/source/browse/#svn/trunk/GServerEngine/NetLibrary">http://code.google.com/p/tpgame/source/browse/#svn/trunk/GServerEngine/NetLibrary</a></p>
<p>问题肯定较多，希望多多指教。<br><br><br>最近一直在构思与写一套游戏AI系统，主要是通过状态机响应事件，更多是想运用自己学习到的一些优秀的算法，以及一些高级</p>
<p>的AI以此来锻炼对一些复杂的数据结构的编写和设计思维的提升。</p>
<p>算法和数据结构方面:<br>1.2D和3D寻路(主要包括2D寻路的初始化条件优化 ，3D的空间划分以及多叉树的划分，以及堆维护)。<br>2.带有更多思维的角色系统(附带更多的数据信息)判断。<br>3.查询线段树和树状数数组的运用。<br>4.一个线性的字符串过滤程序。<br>5.一个动态基于角色的最优二叉查找树的动态维护。(主要解决不同的角色AI触发频率建立一颗最优二叉查找树)<br>6.追踪算法以及游戏的群集算法都会整合到现在的AI系统中。<br><br>设计方面：<br>1.尽量让类之间耦合性更小，复杂度更低，浅显明确。<br><br>注：Ai系统写完会把代码和网络库的最新代码更新都会上传，希望大家多多指教。<br><br><br><br><br></p>
<img src ="http://www.cppblog.com/expter/aggbug/103566.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/expter/" target="_blank">expter</a> 2009-12-20 14:21 <a href="http://www.cppblog.com/expter/archive/2009/12/20/103566.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>3D游戏寻路算法(A*) </title><link>http://www.cppblog.com/expter/archive/2009/10/10/98282.html</link><dc:creator>expter</dc:creator><author>expter</author><pubDate>Sat, 10 Oct 2009 14:50:00 GMT</pubDate><guid>http://www.cppblog.com/expter/archive/2009/10/10/98282.html</guid><wfw:comment>http://www.cppblog.com/expter/comments/98282.html</wfw:comment><comments>http://www.cppblog.com/expter/archive/2009/10/10/98282.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/expter/comments/commentRss/98282.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/expter/services/trackbacks/98282.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;关于游戏寻路，网络上也有很多相关的文章，一般都是已A*为主，他只是一种启发式搜索，最开始写A*是在大三，主要还是做一个路径搜索的算法。&nbsp;<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于游戏中A*的算法优化，由于在搜索的过程中会通过open表和close保存一些结点，为了加快查找效率一般采用对维护的方式，利用map的最小堆(按照估价值的大小排序)来构架数据结构。其实还可以利用线性的hash_map来创建维护。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 而3D中游戏寻路也是采用同样的方法，只是在不同于2D的8个方向搜索而是3*8个方向的搜索。所以他的复杂度之高，在对于一个3维的N*N*N的空间，他的搜索运算为n^3*24，就需要考虑算法中的优化。<br>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 总之一句3D寻路费时又费空间！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是我总结的优化&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1.总体还是利用a*和堆维护。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2.由于点是实心，可以直接进行对角线的行走，也就是对角线行走一步后x,y,z的坐标都会改变，从而降低通过2次二维变换的过程。二步变一步！<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3.利用凸包的方式来优化。<br></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4.把一个场景的3D地图全部细分，利用多叉树进行管理。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关于凸包的优化可以通过这样一个例子说明(因为在2D中更好的描述通过2维的地图)：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; A、假设1要到2的，通过A*的搜索，他会先到0然后发现不能通过在回溯，重新寻找新的路径，这样可能浪费一些搜索时间。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img height=202 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/1.GIF" width=241 border=0><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; B.&nbsp;&nbsp; 可以通过多边形的最小矩形凸包的方式，这样就可以减少不必要的搜索，如图所示。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img height=202 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/2.GIF" width=241 border=0><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;那么1到2就不会经过0点。。因为次区域设置为不可通过。<br><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C.&nbsp;&nbsp; 如果我们要查找的点在我们凸包内，所以我们在寻路最开始应该验证点是否在凸包内，如果在此区域内，在行走时不能过滤这个矩形空间。</p>
<p><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注：游戏中地图一般是不变的，所以这些都是不变，凸包已知，验证点在凸包中也是线性的。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 由于在计算3D的凸包的时候计算量大，最开始采用静态的方式来记录数据。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 简单的3D寻路算法源码(不包含凸包优化)： </p>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="http://www.cppblog.com/Files/expter/3DAStar.rar"><u><font color=#0000ff>/Files/expter/3DAStar.rar</font></u></a> 
<img src ="http://www.cppblog.com/expter/aggbug/98282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/expter/" target="_blank">expter</a> 2009-10-10 22:50 <a href="http://www.cppblog.com/expter/archive/2009/10/10/98282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏中常见的几种追踪算法</title><link>http://www.cppblog.com/expter/archive/2009/10/09/98210.html</link><dc:creator>expter</dc:creator><author>expter</author><pubDate>Fri, 09 Oct 2009 15:57:00 GMT</pubDate><guid>http://www.cppblog.com/expter/archive/2009/10/09/98210.html</guid><wfw:comment>http://www.cppblog.com/expter/comments/98210.html</wfw:comment><comments>http://www.cppblog.com/expter/archive/2009/10/09/98210.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/expter/comments/commentRss/98210.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/expter/services/trackbacks/98210.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp; 所谓追踪，相对于另外一个角色来说是逃跑，首先需要做出追和逃跑的决策判断。<br><br>1.坐标追踪<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 也是最基本追逐方式，他根据要追踪对象的坐标来修改追踪者的坐标，使两者的距离逐渐缩短。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;一个简单的例子:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;&nbsp; m_pPrey;&nbsp;&nbsp; /// 被追踪者<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Point&nbsp;&nbsp; m_pAtta;&nbsp;&nbsp; ///&nbsp; 追踪者<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对于追踪者来说： &nbsp; 新位置 =&nbsp; 旧位置 +&nbsp; XY速度 ;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;m_pAtta.x&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;m_pPrey.x&nbsp;)<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;m_pAtta.x&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;m_pAtta.x&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;m_pPrey.x&nbsp;)<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;m_pAtta.x&nbsp;</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;m_pAtta.y&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;m_pPrey.y&nbsp;)<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;m_pAtta.y&nbsp;</span><span style="COLOR: #000000">++</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">(&nbsp;m_pAtta.y&nbsp;</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000">&nbsp;m_pPrey.y&nbsp;)<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;m_pAtta.y&nbsp;</span><span style="COLOR: #000000">--</span><span style="COLOR: #000000">;</span></div>
<p>&nbsp;<br>2.视线追踪<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 视线追踪方式，主要是描述每一时刻都追踪者会沿着被追逐者之间的直线方向运动。如图所示：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<img style="WIDTH: 423px; HEIGHT: 363px" height=363 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/sightat.JPG" width=423 border=0><br>&nbsp;&nbsp;&nbsp;&nbsp; 通过图可以更好描述此问题，此问题的求解关键在于求出连接追踪者与猎物之间的直线，可以通过向量知道：2个向量想减即可得到。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;可以分别用追踪者与猎物的位置坐标构造出两个向量,假设b 代表追踪者位置向量,a 代表猎物位置向量。做向量减法a-b 便得到了向量c，将c 的起点置于追踪者的位置上,就得到了一条指向猎物的向量c. 此时，令： </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;追踪者X 方向速度&nbsp;/ 追踪者Y 方向速度&nbsp;&nbsp;&nbsp;&nbsp;＝&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;c 向量x 轴分量/ &nbsp; c 向量y 轴分量 .即可求解。<br><br>3.<span style="FONT-SIZE: 10.5pt; FONT-FAMILY: 宋体; mso-ascii-font-family: 'Times New Roman'; mso-bidi-font-family: 'Times New Roman'; mso-font-kerning: 1.0pt; mso-bidi-font-size: 12.0pt; mso-hansi-font-family: 'Times New Roman'; mso-ansi-language: EN-US; mso-fareast-language: ZH-CN; mso-bidi-language: AR-SA">拦截追踪<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所谓拦截追踪，如果考虑的是被追逐的目标太远，如果2者速度一样，或者相差不大，有可能很难追上，玩过实况足球的都知道，如果采用上面的2中追逐方式，可能错过最佳的防守位置。下面是拦截追踪的一个示例图:<br><br>&nbsp;&nbsp;&nbsp; <img height=230 alt="" src="http://www.cppblog.com/images/cppblog_com/expter/pred.GIF" width=288 border=0><br>&nbsp;&nbsp;&nbsp; 对于追踪者来说，他只需要知道被追踪者的位置，方向与速度，讲会计算一个最佳的拦截位置。然后你会发现这只是一个简单的追踪问题。且需要的时间t最少。<br><br><br>整个3种追踪的源码代码 以及 demo都共享：<br><a href="http://www.cppblog.com/Files/expter/chase.rar">/Files/expter/chase.rar</a><br><br>下一篇通过实例demo来记录学习的聚类算法：</span> </p>
<img src ="http://www.cppblog.com/expter/aggbug/98210.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/expter/" target="_blank">expter</a> 2009-10-09 23:57 <a href="http://www.cppblog.com/expter/archive/2009/10/09/98210.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>