C# 导弹系统数学问题(代码很少)

C# 导弹系统数学问题(代码很少),c#,xna,C#,Xna,我想要一枚导弹跟随一名玩家,并遵循以下规则: -当玩家位于相对于导弹的右侧时,以固定速率向右旋转 -否则以相同的速率向左旋转 if (missile.Rotation > 0 && missile.Rotation < Math.PI) { if (angle > missile.Rotation && angle < missile.Rotation + Ma

我想要一枚导弹跟随一名玩家,并遵循以下规则:
-当玩家位于相对于导弹的右侧时,以固定速率向右旋转
-否则以相同的速率向左旋转

            if (missile.Rotation > 0 && missile.Rotation < Math.PI)
            {
                if (angle > missile.Rotation && angle < missile.Rotation + Math.PI)
                {
                    missile.Rotation += 0.05f;
                }
                else
                {
                    missile.Rotation -= 0.05f;
                }
            }
            else
            {
                if (angle < missile.Rotation && angle > missile.Rotation - Math.PI)
                {
                    missile.Rotation -= 0.05f;
                }
                else
                {
                    missile.Rotation += 0.05f;
                }
            }  
            missile.Position += new Vector2((float)(5 * gameTime.ElapsedGameTime.TotalSeconds * Math.Cos(missile.Rotation)), (float)(5 * gameTime.ElapsedGameTime.TotalSeconds * Math.Sin(missile.Rotation)));
if(飞弹旋转>0&&emission.Rotation导弹旋转和角度<导弹旋转+数学PI)
{
导弹旋转+=0.05f;
}
其他的
{
导弹旋转-=0.05f;
}
}
其他的
{
if(角度<导弹旋转&&angle>导弹旋转-数学PI)
{
导弹旋转-=0.05f;
}
其他的
{
导弹旋转+=0.05f;
}
}  
导弹位置+=新矢量2((浮动)(5*gameTime.ElapsedGameTime.TotalSeconds*Math.Cos(导弹旋转)),(浮动)(5*gameTime.ElapsedGameTime.TotalSeconds*Math.Sin(导弹旋转));
有了这个代码,有些导弹似乎会出问题,当我和玩家一起跳的时候,导弹会进入一个无法停止的无休止的循环(它们在一个圆圈中飞行)

坐标系类似于XNA(360/0°位于右侧,270°位于顶部…


有人能帮我吗?

使用欧拉角是一种非常低效的方法。使用向量要容易得多

设p为玩家的位置,M为导弹的位置。你需要计算两个向量:MP和Mr,其中MP=从导弹到玩家的向量,Mr是指向导弹右手侧的向量。现在计算矢量MP和Mr之间的点积。结果的符号告诉你导弹转向的方向。如果为正,则顺时针转动导弹;如果为负,则逆时针转动导弹

为什么这样做有效

两个向量A和B的点积可以写成:

Ax.Bx + Ay.By
而且:

|A|.|B|.cos (theta)
式中,θ是两个向量之间的角度,|x |是向量x的大小。这给了我们:

cos (theta) = (Ax.Bx + Ay.By) / (|A|.|B|)
因为我们只想知道cos(θ)值的符号,正值是+-90度之间的角度,负值是90到270度之间的角度,我们只需要算出分子的符号,分母总是正值!因此,点积的符号将告诉我们目标在哪一边

但是,你在想,向量不是比角度更难使用吗?我不需要做一些触发函数来计算导弹的右向量吗

理想情况下,你不应该在任何事情上使用欧拉角。您应该使用矩阵来存储世界中对象的位置和旋转。导弹的右向量只是导弹位置/方向矩阵的顶行(或第一列,取决于您如何设置系统)。矩阵是渲染硬件用来绘制对象的,因此使用它们不会增加任何开销(事实上,使用角度会增加开销,因为角度符号需要转换为矩阵进行渲染)

编辑:您的代码最终应如下所示:

if (VectorDotProduct (missile.right, player.pos - missil.pos) > 0)
{
   missile.rotate clockwise
}
else
{
   missile.rotate anti-clockwise
}

使用欧拉角是一种非常低效的方法。使用向量要容易得多

设p为玩家的位置,M为导弹的位置。你需要计算两个向量:MP和Mr,其中MP=从导弹到玩家的向量,Mr是指向导弹右手侧的向量。现在计算矢量MP和Mr之间的点积。结果的符号告诉你导弹转向的方向。如果为正,则顺时针转动导弹;如果为负,则逆时针转动导弹

为什么这样做有效

两个向量A和B的点积可以写成:

Ax.Bx + Ay.By
而且:

|A|.|B|.cos (theta)
式中,θ是两个向量之间的角度,|x |是向量x的大小。这给了我们:

cos (theta) = (Ax.Bx + Ay.By) / (|A|.|B|)
因为我们只想知道cos(θ)值的符号,正值是+-90度之间的角度,负值是90到270度之间的角度,我们只需要算出分子的符号,分母总是正值!因此,点积的符号将告诉我们目标在哪一边

但是,你在想,向量不是比角度更难使用吗?我不需要做一些触发函数来计算导弹的右向量吗

理想情况下,你不应该在任何事情上使用欧拉角。您应该使用矩阵来存储世界中对象的位置和旋转。导弹的右向量只是导弹位置/方向矩阵的顶行(或第一列,取决于您如何设置系统)。矩阵是渲染硬件用来绘制对象的,因此使用它们不会增加任何开销(事实上,使用角度会增加开销,因为角度符号需要转换为矩阵进行渲染)

编辑:您的代码最终应如下所示:

if (VectorDotProduct (missile.right, player.pos - missil.pos) > 0)
{
   missile.rotate clockwise
}
else
{
   missile.rotate anti-clockwise
}

我还以为是关于真正的导弹角度=从导弹到目标的角度Player@BojanK:那些不是有[Ada]标签而不是[C#]?:)。。。至于这个问题,你不使用MathHelper.Lerp()或类似方法有什么具体原因吗?@Martin Sojka,是的,我想知道哪个白痴会使用C#这就是我检查它的原因。我也不知道[xna]是什么,我还以为它是关于真正的导弹,角度=从导弹到目标的角度Player@BojanK:那些不是有[Ada]标签而不是[C#]?:)。。。至于这个问题,你不使用MathHelper.Lerp()或类似方法有什么具体原因吗?@Martin Sojka,是的,我想知道哪个白痴会使用C#这就是我检查它的原因。我也不知道