C# 确定两个矢量3点之间的偏航和俯仰

C# 确定两个矢量3点之间的偏航和俯仰,c#,xna,C#,Xna,我读过各种各样的方法来确定两个向量之间的角度,我真的很困惑,所以我需要一些帮助来理解我需要做什么 下面是我的第一人称相机代码 public class FPSCamera : Engine3DObject { public Matrix View { get; private set; } public Matrix Projeciton { get; private set; } private Quaternion rotation; private fl

我读过各种各样的方法来确定两个向量之间的角度,我真的很困惑,所以我需要一些帮助来理解我需要做什么

下面是我的第一人称相机代码

 public class FPSCamera : Engine3DObject
{
    public Matrix View { get; private set; }
    public Matrix Projeciton { get; private set; }

    private Quaternion rotation;
    private float yaw;
    private float pitch;
    private bool isViewDirty;
    private bool isRotationDirty;

    public BoundingFrustum Frustum { get; private set; }

    public bool Changed { get; private set; }

    public Vector3 ForwardVector
    {
        get
        {
            return this.View.Forward;
        }
    }

    public FPSCamera()
        : base()
    {
        this.Position = Vector3.Zero;
        this.rotation = Quaternion.Identity;
        this.yaw = this.pitch = 0;
        this.isViewDirty = true;
        this.isRotationDirty = false;


    }

    public void SetPosition(Vector3 position)
    {
        this.Position = position;
        this.isViewDirty = true;
        this.Update(null);
    }

    public void Initialize(float aspectRatio)
    {
        this.Projeciton = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspectRatio, 1f, 1000f);
    }

    public void Update(GameTime gameTime)
    {
        this.Changed = false;

        if (isRotationDirty)
        {
            if (yaw > MathHelper.TwoPi)
            {
                yaw = yaw - MathHelper.TwoPi;
            }

            if (yaw < -MathHelper.TwoPi)
            {
                yaw = yaw + MathHelper.TwoPi;
            }

            if (pitch > MathHelper.TwoPi)
            {
                pitch = pitch - MathHelper.TwoPi;
            }

            if (pitch < -MathHelper.TwoPi)
            {
                pitch = pitch + MathHelper.TwoPi;
            }

            this.rotation = Quaternion.CreateFromYawPitchRoll(yaw, pitch, 0);
            this.isRotationDirty = false;
            this.isViewDirty = true;
            this.Changed = true;
        }

        if (isViewDirty)
        {
            Vector3 up = Vector3.Transform(Vector3.Up, rotation);
            Vector3 target = Vector3.Transform(Vector3.Forward, rotation) + Position;
            this.View = Matrix.CreateLookAt(this.Position, target, up);
            this.isViewDirty = false;

            if (this.Frustum == null)
            {
                this.Frustum = new BoundingFrustum(this.View * this.Projeciton);
            }
            else
            {
                this.Frustum.Matrix = (this.View * this.Projeciton);
            }

            this.Changed = true;
        }
    }

    public void Move(Vector3 distance)
    {
        this.Position += Vector3.Transform(distance, rotation);
        this.isViewDirty = true;
    }

    public void Rotate(float yaw, float pitch)
    {
        this.yaw += yaw;
        this.pitch += pitch;
        this.isRotationDirty = true;
    }

    public void LookAt(Vector3 lookAt)
    {

    }
}
公共类摄像机:Engine3DObject
{
公共矩阵视图{get;private set;}
公共矩阵项目{get;private set;}
私有四元数旋转;
私人浮动偏航;
私人浮球;
私人厕所脏兮兮;
私人厕所是肮脏的;
公共边界截头体截头体{get;private set;}
公共布尔值已更改{get;private set;}
公共向量3前向向量
{
得到
{
返回此.View.Forward;
}
}
公共摄像机()
:base()
{
这个。位置=矢量3。零;
this.rotation=Quaternion.Identity;
this.yaw=this.pitch=0;
this.isViewDirty=true;
this.isRotationDirty=false;
}
公共无效设置位置(矢量3位置)
{
这个位置=位置;
this.isViewDirty=true;
此.Update(空);
}
公共void初始化(float aspectRatio)
{
this.Projeciton=Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,aspectRatio,1f,1000f);
}
公开作废更新(游戏时间游戏时间)
{
这个.Changed=false;
如果(isRotationDirty)
{
如果(偏航>MathHelper.TwoPi)
{
偏航=偏航-MathHelper.TwoPi;
}
if(偏航<-MathHelper.TwoPi)
{
偏航=偏航+MathHelper.TwoPi;
}
if(俯仰>MathHelper.TwoPi)
{
俯仰=俯仰-MathHelper.TwoPi;
}
if(节距<-MathHelper.TwoPi)
{
俯仰=俯仰+MathHelper.TwoPi;
}
this.rotation=Quaternion.CreateFromYawPitchRoll(偏航,俯仰,0);
this.isRotationDirty=false;
this.isViewDirty=true;
这个。改变了=真;
}
如果(isViewDirty)
{
向量3向上=向量3.变换(向量3.向上,旋转);
Vector3目标=Vector3.变换(Vector3.向前,旋转)+位置;
this.View=Matrix.CreateLookAt(this.Position,target,up);
this.isViewDirty=false;
if(this.trustum==null)
{
this.Frustum=新边界Frustum(this.View*this.Projeciton);
}
其他的
{
this.Frustum.Matrix=(this.View*this.Projeciton);
}
这个。改变了=真;
}
}
公共无效移动(矢量3距离)
{
此.Position+=Vector3.Transform(距离、旋转);
this.isViewDirty=true;
}
公共空隙旋转(浮动偏航、浮动俯仰)
{
这是偏航+=偏航;
this.pitch+=音高;
this.isRotationDirty=true;
}
公共无效注视(矢量3注视)
{
}
}

“lookat”方法是空白的,因为我正在尝试找出如何执行它。我移动相机,使其位置为(500500),需要它查看(0,0,0),但我不知道如何获得它们之间的偏航和俯仰,以便正确设置旋转。我读过关于规范化向量和使用交叉点积的书,但是你不能规范化(0,0,0),因为它没有方向,所以我有点不知所措。任何帮助都将不胜感激。

首先,您已经有了一种计算适当矩阵的方法
matrix.CreateLookAt(this.Position,target,up)
。此方法创建适当的矩阵

除此之外,您要使用的不是观察位置点,而是从摄影机到观察点的方向。所以在你的例子中,它是[0,0,0]-[500500500]。您还需要“向上”方向来计算角度的缠绕方向

这里有相关的讨论:

在这里,您对变换矩阵有了更多的解释:

您似乎希望能够以两种不同的方式操作您的相机:

1.)增加或减少一点偏航或俯仰,并让摄像头做出相应的响应。
2.)让摄像头查看已知位置,然后反向计算俯仰角和偏航角,以便在需要时在后续帧上执行#1

我认为,让您感到困难的是,您希望存储总体俯仰角和偏航角,以便以后使用。你可能会听到一些有经验的3d程序说,如果你认为你需要存储角度,你可能做错了()。不管怎样,如果你能放开这些角度,你的相机类会简单得多。这里有一个例子。这两种公共方法允许您通过1.)添加俯仰、偏航或平移或2.)将相机设置为查看世界上的特定点来对其进行操作。它还允许您在任何时候使用任何一种方法。由于不考虑绝对俯仰角和偏航角,代码更简单

namespace WindowsGame1
{
    class FPSCamera
    {
        public Matrix View;
        public Matrix Proj;
        public Vector3 Position, Target;


        public FPSCamera(float aspect)
        {

            Proj = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, aspect, 1f, 1000f);
            Target = Vector3.Forward;
            SetViewMatrix();
        }

        public void UpdateCameraByPitchYawTranslation(float amountToPitchThisFrame, float amountToYawThisFrame, Vector3 amountToTranslateThisFrame)
        {
            Position += amountToTranslateThisFrame;
            Target += amountToTranslateThisFrame;

            Matrix camera = Matrix.Invert(View);
            Target = Vector3.Transform(Target - Position, Matrix.CreateFromAxisAngle(camera.Right, amountToPitchThisFrame)) + Position;
            Target = Vector3.Transform(Target - Position, Matrix.CreateFromAxisAngle(Vector3.Up, amountToYawThisFrame)) + Position;

            SetViewMatrix();
        }

        public void SetCameraToLookAtSpecificSpot(Vector3 spotToLookAt)
        {
            Target = spotToLookAt;
            SetViewMatrix();
        }

        private void SetViewMatrix()
        {
            View = Matrix.CreateLookAt(Position, Target, Vector3.Up);
        }

    }
}

如果需要,您也可以使用公共方法将相机位置设置为特定位置。

好的,我明白了。。。我曾经考虑过简化它,因为它看起来有点臃肿和不必要。我将实施它,看看它是如何运行的。我如何向前移动相机(即它所面对的方向?)。此时,如果我通过运动矢量,它会移动相机,但只在轴上移动,而不是在相机面对的方向上移动。我还需要计算出相机在其他功能中所面对的角度,但我相信我可以通过某种方式使用目标来做到这一点。你可以添加这样的方法来向前或向后移动。这会使它前后移动,但不会朝着相机所面对的方向移动!我知道这是FPS相机,但它只是名字而已!我需要相机向相机所面对的方向移动。忽略我最后的评论,我使用了错误的方法。这个w