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