微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

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

所以我正在尝试进行boids模拟。我正在尝试实施第一条规则,即每个 boid 必须避开附近的 boid。我有一个名为 boids 的 std::vector 中的所有 boids。每个 boids 都有一个名为 std::vectorwithinSensoryRange,它保存所有 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() 返回 boid.rotationAngle + 90 degrees,所以我正在检查方向角但添加rotationAngle

感谢您的帮助。

解决方法

经过几天的努力,我终于让它工作了。我从 this 论文中得到了这个想法。特别是这句话:

每个 boid 都会考虑它与其他群体成员的距离 它的邻域并在其上施加排斥力 相反的方向,按距离的倒数缩放。

下面的代码和上面的句子完全一样。

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;
        } 

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。