我如何计算方向向量以避开附近的代理

How can I calculate the direction vector to steer away from nearby agents

所以我正在尝试模拟类群。我正在尝试实施第一条规则,即每个 boid 必须远离附近的 boids。我在一个名为 boids 的 std::vector 中拥有所有 boids。每个 boids 都有一个名为 withinSensoryRangestd::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;
        }