AI for Game Developers -- Bresenham 算法大揭秘

AI for Game Developers -- Bresenham 算法大揭秘

我在看这本书的英文版时的chapter2部分,看到了此算法,当时很是郁闷,有很多地方都不明白为什么要那么编写代码,到底是什么意思.后来就把那本书丢在那里,没在看了,直到昨天我家也装了宽带,yeah,我立刻马上赶紧去网上搜索了一把这个算法,不过发现都是在宏观上的讲解,没有细化到每一个语句上,我简要看了一下思想,就爬在床上?拿了张纸,画了个图,认真研究了一下,没想到我还真搞明白了,好开心啊,所以今天晚上回来我把我的这个成果写下来,为了还在为这个算法迷茫的人点燃一盏小明灯. :)

把这本书的这个算法写下来,清楚地就不解释了,不清楚的解释下,不过是我自己的理解,对不对,各有所见吧.

void ai_Entity::BuildPathToTarget(void)
{

//初始化开始路径
int nextCol = col;  //这个col在画面上就是x
int nextRow = row;  //这个row在画面上就是y

//算出delta值(x和y所要走的路程)
int deltaRow = endRow - row;
int deltaCol = endCol - col;

//此段for循环和算法无关,只是清空储存要走的路径的数组
for(currentStep = 0; currentStep < kMaxPathLength; currentStep++)
{
    pathRow[currentStep] = -1;
    pathCol[currentStep] = -1;
}

currentStep = 0;

//设置目标位置
pathRowTarget = endRow;
pathColTarget = endCol;

//判断走的步长的方向
if(deltaRow < 0) stepRow = -1; else stepRow = 1;
if(deltaCol < 0) stepCol = -1; else stepCol = 1;

//同乘以2等于没乘,步长(stepRow/stepCol)跟此也无关,不知为何*2,保证精度?
deltaRow = abs(deltaRow * 2);
deltaCol = abs(deltaCol * 2);

//记录开始路径
pathRow[currentStep] = nextRow;
pathCol[currentStep] = nextCol;

currentStep++ ;

/*
下面开始 Bresenham algorithm 的主体部分
*/

//这个变量是一个关键点,它主要记录的是把fraction/dx(或fraction/dy)[可以把比值看作斜率,比值>=1时,fraction代表的方向需要走一个stepLength]转换为加减法的标志值.
//fraction其实为delta值较弱的一方的累积值.
int fraction = 0;

//如果x要走的部分比y要长

if(deltaCol > deltaRow)
{
    //此处我开始看,怎么也不明白为什么要乘以2,为啥要乘以2呢.
    //其实是为了让row(y)方向的路径在此算法开始时就有反映(如果此方向必须有反映的话)
    //因为既然deltaRow < deltaCol,所以*2 在 deltaRow >= deltaCol,可以做出立刻改变坐标的行为.
    //如果不*2,使 fraction = deltaRow - deltaCol,依然可以达到此算法的目的,只是第一个移动的反映比*2要晚一步.
   //坚决不能让 fraciton = 0, 因为一开始此标志作为delta小方是否要移动的标志,会造成走直线时,开始就多走一步,偏离某一方向一步;如果在此基础上改变if(fraction>=0)为if(fraction>0),则会造成在走对角线的路线时,最后在某一方向上缺少一步.
   //坚决不能*3或以上,因为*2造成的影响只有一步,如果超过*2,在某些情况则造成不准确的偏离.
    fraction = deltaRow * 2 - deltaCol;

    while(nextCol!=endCol)
    {
        //此处为fraction[即斜率的代表] (累积的fraction Row(y)/deltaCol(x) >=1 ) [画图会更直接的表现出来]
        if(fraction >= 0)
        {
        nexRow = nextRow + stepRow;
         //削弱Row(y)的积累程度[画图会更直接的表现出来]
         fraction = fration - deltaCol;
         }//if

 nextCol = nextCol + stepCol;

 //因为每一次Col都在变化,而fraction Row只有在积累到>=Col的时候才能走一步,这里为积累的动作. [画图会更直接的表现出来]
 fraction = fraction + deltaRow;

 pathRow[currentStep] = nextRow;
 pathCol[currentStep] = nextCol;
 currentStep ++;
    }//while
}
//此下部分与上面原理相同,故略掉了啊
else
{
    fraction = deltaCol*2 - deltaRow;
    while(nextRow!=endRow)
    {
      if(fraction>=0)
      {
     nextCol = nextCol + stepCol;
     fraction = fraction + deltaRow;  
     }
 nextRow = nextRow + stepRow;
 fraction = fraction + deltaCol;
 pathRow[currentStep] = nextRow;
 pathCol[currentStep] = nextCol;
 currentStep++;

    }//while

}//else

}//ai_Entity 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值