我如何计算方向向量以避开附近的代理
How can I calculate the direction vector to steer away from nearby agents
所以我正在尝试模拟类群。我正在尝试实施第一条规则,即每个 boid 必须远离附近的 boids。我在一个名为 boids 的 std::vector
中拥有所有 boids。每个 boids 都有一个名为 withinSensoryRange
的 std::vector
,它包含所有在 boids 感官范围内的 boids。我解决这个问题的方法是为每个 boid 计算 withinSensoryRange
向量中最近的 boid,然后尝试远离该 boid。
for (auto& boid : boids)
{
if (!boid->withinSensoryRange.empty())
{
Boid* closest = boid->withinSensoryRange[0];
float lowest = INFINITY;
for (auto& boidwithinRange : boid->withinSensoryRange)
{
float distance = sqrtf((boid->position.x - boidwithinRange->position.x) * (boid->position.x - boidwithinRange->position.x) +
(boid->position.y - boidwithinRange->position.y) * (boid->position.y - boidwithinRange->position.y));
if (distance < lowest)
{
lowest = distance;
closest = boidwithinRange;
}
}
///THIS BIT BELOW IS THE ONE THAT DOES NOT WORK PROPERLY.
///I have verified that everything else works properly.
float difference = boid->GetDirectionAngle() - closest->GetDirectionAngle();
if (difference != 0)
boid->rotationAngle += (1.0f / difference) * 0.009f;
}
}
所以我想,如果我加上差值的倒数,那么差值越大,它们就会转动得越慢,反之亦然。我还将它乘以 0.009f 以减少它们的移动性。我不知道为什么,但这种方法似乎并没有真正奏效。我需要一种正确的方法来计算远离 closest
boid 的方向矢量。
顺便说一下,boid.GetDirectionAngle()
returns boid.rotationAngle + 90 degrees
,所以我正在检查方向角但添加到 rotationAngle
。
感谢您的帮助。
经过几天的努力,我终于让它工作了。我从 this 论文中得到了这个想法。特别是这句话:
每个鸟群都会考虑它与其他鸟群伙伴的距离
它的邻域并在其中施加排斥力
相反方向,按距离的倒数缩放。
下面的代码与上面的句子完全相同。
for (auto& arrow : arrows)
{
olc::vf2d totalInfluence;
for (auto& inRange : arrow->withinFovRange)
{
float distance = GetDistance(arrow->position, inRange->position);
olc::vf2d vecToBoidInRange = (arrow->position - inRange->position).norm();
if (distance != 0)
vecToBoidInRange *= (1.0f / distance);
totalInfluence += vecToBoidInRange;
}
arrow->rotationAngle += std::atan2(totalInfluence.y, totalInfluence.x) * rotationMobility;
}
所以我正在尝试模拟类群。我正在尝试实施第一条规则,即每个 boid 必须远离附近的 boids。我在一个名为 boids 的 std::vector
中拥有所有 boids。每个 boids 都有一个名为 withinSensoryRange
的 std::vector
,它包含所有在 boids 感官范围内的 boids。我解决这个问题的方法是为每个 boid 计算 withinSensoryRange
向量中最近的 boid,然后尝试远离该 boid。
for (auto& boid : boids)
{
if (!boid->withinSensoryRange.empty())
{
Boid* closest = boid->withinSensoryRange[0];
float lowest = INFINITY;
for (auto& boidwithinRange : boid->withinSensoryRange)
{
float distance = sqrtf((boid->position.x - boidwithinRange->position.x) * (boid->position.x - boidwithinRange->position.x) +
(boid->position.y - boidwithinRange->position.y) * (boid->position.y - boidwithinRange->position.y));
if (distance < lowest)
{
lowest = distance;
closest = boidwithinRange;
}
}
///THIS BIT BELOW IS THE ONE THAT DOES NOT WORK PROPERLY.
///I have verified that everything else works properly.
float difference = boid->GetDirectionAngle() - closest->GetDirectionAngle();
if (difference != 0)
boid->rotationAngle += (1.0f / difference) * 0.009f;
}
}
所以我想,如果我加上差值的倒数,那么差值越大,它们就会转动得越慢,反之亦然。我还将它乘以 0.009f 以减少它们的移动性。我不知道为什么,但这种方法似乎并没有真正奏效。我需要一种正确的方法来计算远离 closest
boid 的方向矢量。
顺便说一下,boid.GetDirectionAngle()
returns boid.rotationAngle + 90 degrees
,所以我正在检查方向角但添加到 rotationAngle
。
感谢您的帮助。
经过几天的努力,我终于让它工作了。我从 this 论文中得到了这个想法。特别是这句话:
每个鸟群都会考虑它与其他鸟群伙伴的距离 它的邻域并在其中施加排斥力 相反方向,按距离的倒数缩放。
下面的代码与上面的句子完全相同。
for (auto& arrow : arrows)
{
olc::vf2d totalInfluence;
for (auto& inRange : arrow->withinFovRange)
{
float distance = GetDistance(arrow->position, inRange->position);
olc::vf2d vecToBoidInRange = (arrow->position - inRange->position).norm();
if (distance != 0)
vecToBoidInRange *= (1.0f / distance);
totalInfluence += vecToBoidInRange;
}
arrow->rotationAngle += std::atan2(totalInfluence.y, totalInfluence.x) * rotationMobility;
}