确定两个Vector3点之间的偏航和俯仰

本文关键字:之间 Vector3 两个 | 更新日期: 2023-09-27 18:11:58

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

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

 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)
    {
    }
}

"look"方法是空白的,因为我正在试图弄清楚如何做到这一点。我移动相机,所以它的位置是(500,500,500),需要它看(0,0,0),但我不知道如何获得它们之间的偏航和俯仰,所以我可以设置正确的旋转。我读过关于向量的归一化以及使用叉乘和点积,但是你不能归一化(0,0,0)因为它没有方向所以我有点不知所措。

确定两个Vector3点之间的偏航和俯仰

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

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

如果你想的话,你也可以创建一个公共方法来设置摄像头的位置。

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

除此之外,你想要的工作不是一个观察位置点,而是从相机到观察点的方向。在你的例子中,它是[0,0,0]-[500,500,500]。你还需要"上"方向来计算角度的缠绕方向。

这里有相关的讨论:计算LookAt矩阵

这里你有更多关于变换矩阵的解释:http://www.math.washington.edu/王/coursedir m308a01/项目/m308a01-pdf/yip.pdf