XNA 二维视场

发布于 2024-09-30 23:58:39 字数 627 浏览 8 评论 0原文

我正在 XNA 中开发一款基于集群的 2D 游戏。我已经实现了 Craig Reynold 的集群技术,现在我想动态地为团队分配一个领导者,以引导其实现目标。

为此,我想找到一个前面没有任何其他代理的游戏代理,并使其成为领导者,但我不确定其数学原理。

目前我有:

Vector2 separation = agentContext.Entity.Position - otherAgent.Entity.Position;

float angleToAgent = (float) Math.Atan2(separation.Y, separation.X);
float angleDifference = Math.Abs(agentContext.Entity.Rotation - angleToAgent);
bool isVisible = angleDifference >= 0 && angleDifference <= agentContext.ViewAngle;

agentContext.ViewAngle 是一个弧度值,我尝试使用它来尝试获得正确的效果,但这主要导致所有代理都被分配为领导者。

谁能指出正确的方向来检测一个实体是否位于另一个实体的“圆锥体”视图内?

I'm working on a 2D game in XNA based around flocking. I've implemented Craig Reynold's flocking technique and now I want to dynamically assign a leader to the group to guide it towards a target.

To do this, I want to find a game agent that does not have any other agents in front of it and make it the leader but I'm unsure of the maths for this.

Currently I have:

Vector2 separation = agentContext.Entity.Position - otherAgent.Entity.Position;

float angleToAgent = (float) Math.Atan2(separation.Y, separation.X);
float angleDifference = Math.Abs(agentContext.Entity.Rotation - angleToAgent);
bool isVisible = angleDifference >= 0 && angleDifference <= agentContext.ViewAngle;

agentContext.ViewAngle is a radians values which I have played with to try and get the right effect but this mostly results in all agents being assigned as leaders.

Can anyone point me in the right direction to detect if an entity is within a "cone" of view of another entity?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

后知后觉 2024-10-07 23:58:39

您需要标准化 Atan2 函数的输入。另外,减去角度时必须小心,因为结果可能超出 pi 到 -pi 的范围。我更喜欢使用方向向量而不是角度,因此您可以对此类事情使用点积运算,因为这往往更快,而且您不必担心超出规范范围的角度。

以下代码应该可以达到您想要的结果:

    double CanonizeAngle(double angle)
    {
        if (angle > Math.PI)
        {
            do
            {
                angle -= MathHelper.TwoPi;
            }
            while (angle > Math.PI);
        }
        else if (angle < -Math.PI)
        {
            do
            {
                angle += MathHelper.TwoPi;
            } while (angle < -Math.PI);
        }

        return angle;
    }

    double VectorToAngle(Vector2 vector)
    {
        Vector2 direction = Vector2.Normalize(vector);
        return Math.Atan2(direction.Y, direction.X);
    }

    bool IsPointWithinCone(Vector2 point, Vector2 conePosition, double coneAngle, double coneSize)
    {
        double toPoint = VectorToAngle(point - conePosition);
        double angleDifference = CanonizeAngle(coneAngle - toPoint);
        double halfConeSize = coneSize * 0.5f;

        return angleDifference >= -halfConeSize && angleDifference <= halfConeSize;
    }

You need to normalize the input to the Atan2 function. Also you have to be careful when subtracting angles because the result can be outside the range pi to -pi. I prefer to use direction vectors rather than angles so you can use the dot product operation for this sort of thing as that tends to be faster and you don't have to worry about angles outside of the canonical range.

The following code should achieve the result you are after:

    double CanonizeAngle(double angle)
    {
        if (angle > Math.PI)
        {
            do
            {
                angle -= MathHelper.TwoPi;
            }
            while (angle > Math.PI);
        }
        else if (angle < -Math.PI)
        {
            do
            {
                angle += MathHelper.TwoPi;
            } while (angle < -Math.PI);
        }

        return angle;
    }

    double VectorToAngle(Vector2 vector)
    {
        Vector2 direction = Vector2.Normalize(vector);
        return Math.Atan2(direction.Y, direction.X);
    }

    bool IsPointWithinCone(Vector2 point, Vector2 conePosition, double coneAngle, double coneSize)
    {
        double toPoint = VectorToAngle(point - conePosition);
        double angleDifference = CanonizeAngle(coneAngle - toPoint);
        double halfConeSize = coneSize * 0.5f;

        return angleDifference >= -halfConeSize && angleDifference <= halfConeSize;
    }
寒江雪… 2024-10-07 23:58:39

我认为你想测试+/-角度,而不仅仅是+(即angleDifference >= -ViewAngle/2 &&angleDifference <= ViewAngle/2)。或者使用绝对值。

I think you want to test +/- angle, not just + (ie angleDifference >= -ViewAngle/2 && angleDifference <= ViewAngle/2). Or use absolute value.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文