背景
Reynolds在1999年发表了论文Steering Behaviors for Autonomous Characters,他在里面用“小车”(vehicle)描述自治智能体,我们也打算使用这个术语。
6.3 转向力
*思路:转向力 = 所需速度 - 当前速度
转向力在本质上是当前速度的误差体现:“我应该朝着这个方向运动,实际上却朝着另一个方向运动。误差就是两个方向之间的差异。”
PVector desired = PVector.sub(target, location);
*改进:
*原理:
*特殊:
小车的起始状态是静止的(当前速度为0),转向力就等于所需速度。
*不足:
我们没有考虑小车的转向能力,可以通过限制转向力的大小控制转向能力。
*改进:
直接用float maxforce; 进行限制
6.4 到达行为
*思路:
假设目标附近有一个给定半径的圆圈,如果小车运动到圆圈之内,它就减速——如果小车位于圆圈的边缘,它的所需速度就等于最大速率;如果已经位于目标位置,所需速度就等于0。
6.5 所需速度
在游走(wandering)行为中,Reynolds是这么定义所需速度的:
“游走是一种随机性转向,它有一种远期秩序,下一帧的转向角度和当前帧的转向角度相关。
这种移动方式比单纯为每一帧产生随机方向更有趣。”
*思路:
小车把自己前方某处当作未来位置,在这个未来位置上画一个半径为r的圆圈,并在圆上随机选择一个点,在每一帧动画中,这个点都是随机确定的。我们可以把这个点当做目标位置,并由此计算所需速度。
*思路2:
*实现:
当前速度 + 垂直于墙向外的速度 = 所需速度
所需速度 - 当前速度 = 墙的斥力
if (location.x > 25)
{
PVector desired = new PVector(maxspeed, velocity.y);
PVector steer = PVector.sub(desired, velocity);
steer.limit(maxforce);
applyForce(steer);
}
*俯视图:
6.6 流场
每个单元格都有一个向量指向特定方向,这样的模型就是流场。
在小车的移动过程中,它会说:“位于我下方的箭头就是我的所需速度!”
*实现:
1.随机
for (int i = 0; i < cols; i++) //使用嵌套循环遍历流场的所有行和所有列
{
for (int j=0; j < rows; j++)
{
field[i][j] = PVector.2D(); //一个随机向量
}
}
2.Perlin噪声(弧度映射成角度)
float xoff =