首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何确保boids 100%避开墙壁

如何确保boids 100%避开墙壁
EN

Stack Overflow用户
提问于 2021-05-20 06:42:48
回答 1查看 87关注 0票数 0

我在试着做机器人的模拟。目前,我有一个他们可以四处漫游的世界,他们必须避开障碍物。我的障碍物被定义为线,我正在使用线相交来查看它前面是否有任何墙,如果有,我就避开它。实际上,在direction angle + FOVdirection angle - FOV有两行代码。如果这两条线中的任何一条发生碰撞,弹体就会转向。我设置的转向条件是,只要这两条线的点积平均值小于direction anglecos,就继续转向。下面是代码。

代码语言:javascript
复制
for (auto& boid : boids)
        {
            //finding the tow vectors to + and - fov from the direction angle
            olc::vf2d lessFov = { (-std::cos(boid.DirectionAngle() - boid.collisionFov) * boid.collisionSensoryRange) + boid.position.x,
                (-std::sin(boid.DirectionAngle() - boid.collisionFov) * boid.collisionSensoryRange) + boid.position.y};

            olc::vf2d plusFov = { (-std::cos(boid.DirectionAngle() + boid.collisionFov) * boid.collisionSensoryRange) + boid.position.x,
                (-std::sin(boid.DirectionAngle() + boid.collisionFov) * boid.collisionSensoryRange) + boid.position.y };

            for (auto& obs : map.obstacles)
            {
                olc::vf2d intersectionPoint1{};
                olc::vf2d intersectionPoint2{};

                if (checkLineIntersect(lessFov, boid.position, obs.p1, obs.p2, intersectionPoint1) ||
                    checkLineIntersect(plusFov, boid.position, obs.p1, obs.p2, intersectionPoint2))
                {

                    //This is the problem
                    if (boid.position.dot( (intersectionPoint1 + intersectionPoint2) / 2 ) < std::cos(boid.DirectionAngle()))
                        boid.rotationAngle -= elapsedTime * obstacleAvoidancePriority;
                    else
                        boid.rotationAngle += elapsedTime * obstacleAvoidancePriority;
                }
            }

        }

我几乎对它给我的结果感到满意,除了偶尔会有一些boids设法穿过墙壁(这种情况很少见,但也有发生),比如下面图片中被困在盒子里的那个。它是在外面产卵的,但还是设法进来了。

我想要一种确保弹体永远不会穿墙的方法。谢谢。

编辑:

我只是注意到在这部分代码中,else子句从未被执行过。这种情况只是我对点积的有限理解而虚构出来的,因为我希望它们不要总是转向同一个方向。

代码语言:javascript
复制
//This is the problem
if (boid.position.dot( (intersectionPoint1 + intersectionPoint2) / 2 ) < std::cos(boid.DirectionAngle()))
    boid.rotationAngle -= elapsedTime * obstacleAvoidancePriority;
else
    boid.rotationAngle += elapsedTime * obstacleAvoidancePriority;

这是我尝试过的另一种方法。

代码语言:javascript
复制
bool i1 = checkLineIntersect(lessFov, boid.position, obs.p1, obs.p2, intersectionPoint1);
bool i2 = checkLineIntersect(plusFov, boid.position, obs.p1, obs.p2, intersectionPoint2);

if (i1 && !i2)
    boid.rotationAngle += elapsedTime * obstacleAvoidancePriority;
else if(i2 && !i1)
    boid.rotationAngle -= elapsedTime * obstacleAvoidancePriority;
else if(i1 || i2)
    if (i1 > i2)
        boid.rotationAngle += elapsedTime * obstacleAvoidancePriority;
    else
        boid.rotationAngle -= elapsedTime * obstacleAvoidancePriority; 

这个确实给了我“转向随机方向”的效果,但有更多的泄漏。

EN

回答 1

Stack Overflow用户

发布于 2021-05-20 07:13:34

看起来你在比较一个点积和一个cos。前者可以有任何值,后者仅限于[-1,+1]。这是可疑的。

此外,虽然boid.DirectionAngle()没有显式定义,但它看起来是一个绝对角度(相对于坐标系)。因此,cos(boid.DirectionAngle())是沿坐标系x轴的组件。但是左边的点项是独立于坐标系的。这同样令人怀疑。

我可能会建议对点积进行缩放,但数学计算似乎太错误了,无法修复。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67611829

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档