C# 在3D中随时间旋转
我正在与Xna 4合作,做一个游戏,我有一个游戏对象(宇宙飞船),它在Y轴=0平面上的3D世界中移动。。Aka 2.5D 直到现在,我使用了一个非常复杂的角度计算来创建两个向量之间的旋转,但是该算法缺乏考虑对象已经旋转的能力。所以结果很有趣。。 因此,我希望有人能给我展示一种智能且易于实现的方法来使用矩阵和向量数学,来做这种随时间旋转的事情 我在以前的搜索中注意到,人们的对象类中有以下变量: -位置向量3 -右向量3 -向上矢量3 -旋转矩阵 -变换矩阵 -速度矢量3 -等等 我经常问自己,为什么一个简单的当前职位需要这么多变量。。或者我不明白。。无论如何 我现在有位置、旋转和transformsMatrix,我想知道我还需要什么以及如何计算它,然后你将如何随着时间的推移实现旋转 我的右键单击移动命令trig调用的方法在单击发生的Y=0平面上发送一个矢量3位置C# 在3D中随时间旋转,c#,xna,rotation,C#,Xna,Rotation,我正在与Xna 4合作,做一个游戏,我有一个游戏对象(宇宙飞船),它在Y轴=0平面上的3D世界中移动。。Aka 2.5D 直到现在,我使用了一个非常复杂的角度计算来创建两个向量之间的旋转,但是该算法缺乏考虑对象已经旋转的能力。所以结果很有趣。。 因此,我希望有人能给我展示一种智能且易于实现的方法来使用矩阵和向量数学,来做这种随时间旋转的事情 我在以前的搜索中注意到,人们的对象类中有以下变量: -位置向量3 -右向量3 -向上矢量3 -旋转矩阵 -变换矩阵 -速度矢量3 -等等 我经常问自己,为什
public void MoveCommand(Vector3 pos){ }
我对此进行了测试,给出的“位置”是准确的。任何帮助都将不胜感激 您应该根据需要的旋转检查Matrix.CreateRotationX Y或Z。 十、 Y或Z是旋转轴, 如果选择Y,将看到“2D”旋转(偏航),因为这是用作深度的轴。 如果选择X或Z轴,您将看到“3D”旋转(俯仰和滚动) 代码应该如下所示:
WorldMatrix = Rotations * Translation
float desiredRotation = 0, currentRotation = 0, totalElapsed = 0, timePerFrame = 0.05f;
if (desiredRotation != 0) {
totalElapsed += elapsed;
if (totalElapsed > timePerFrame) {
if (isRotationComplete()) {
rotX += MathHelper.ToRadians(desiredRotation);
currentRotation = desiredRotation = 0;
} else if (desiredRotation > currentRotation) {
currentRotation += shipTurnSpeed;
} else if (desiredRotation < currentRotation) {
currentRotation -= shipTurnSpeed;
}
totalElapsed -= timePerFrame;
}
}
在哪里
旋转=矩阵。创建旋转X(角度弧度)
及
平移=矩阵。创建平移(位置)
世界矩阵是影响模型的矩阵,视图和投影取决于摄影机
现在,如果你想知道向量之间的角度,你应该检查点积或atan2函数,因为你在2D中
Vector3 Position;
float Rotation;
Matrix World
{
get
{
return Matrix.CreateRotationZ(Rotation) * Matrix.CreateTranslation(Position);
}
}
public void RotateInstantly(Vector3 position)
{
Rotation = Math.Atan2(Position.Y - position.Y, Position.x - position.x);
}
public void RotateIncremently(Vector3 position, float maxStep)
{
float targetRotation = Math.Atan2(Position.Y - position.Y, Position.x - position.x);
float diff = targetRotation - Rotation;
if (Math.Abs(diff) > maxStep)
{
if (targetRotation > Rotation)
Rotation += maxStep;
else
Rotation -= maxStep;
}
else
Rotation = targetRotation;
}
您可以这样递增地使用旋转:*
float dt=(float)gameTime.ElapsedGameTime.TotalSeconds
float maxRotationVelocity=Math.TwoPi//2*Pi是一次旋转
旋转增量(目标位置,最大旋转速度*dt) 感谢Stig Rune Skansgård的回复(如果您的丹麦hi5),我修正了我的旧角度计算,并使其在任何情况下都能工作。。所以我想我会用对我有效的解决方案来回答我自己的问题,这样未来的游客就可以从中受益。。这是一个非常大的Ship类+一个用于计算角度的辅助方法的片段:
public static float CalculateAngleFromVectors(Vector3 v1, Vector3 v2) {
float x = 0;
float X = v2.X - v1.X,
Z = v2.Z - v1.Z;
if (Z == 0) {
x = (X < 0 ? 90 : 270);
} else if (X == 0) {
x = (Z < 0 ? 180 : -180);
} else {
float temp = MathHelper.ToDegrees((float)Math.Atan(X / Z));
if (X < 0) {
x = (Z < 0 ? Math.Abs(temp) : 180 - Math.Abs(temp));
} else {
x = (Z < 0 ? 360 - Math.Abs(temp) : Math.Abs(temp) + 180);
}
}
return x;
}
旋转完成时,rotX变量在我的动画中设置,也在初始化时设置。。下面是我如何使用我的第一个代码片段为我生成的旋转角度:
public void MoveToPosition(Vector3 pos) {
desiredRotation = (CalculateAngleFromVectors(position, pos) - MathHelper.ToDegrees(rotX));
isMoving = true;
}
。。这使得旋转、变换和移动设置可以顺利定制。。在一个XZ平面上。。Y轴向上,始终为0
如果您有任何建议、改变或想法,可以随时对此发表评论。。我总是乐于改进。。感谢您的回复,希望这能帮助很多新开发人员,我花了很长时间才从网上收集到这些东西
PS.旋转可直接应用于rotX进行瞬间旋转,绕过动画和转速
关于
MatriXz我建议在上问这个问题,我感觉那边的人更熟悉这种东西。好吧,我喜欢这种方法,尝试了一下,但出于某种原因,它会产生非常奇怪的结果。。在你的例子中,你将如何计算旋转浮动?好吧,它应该只取决于你的游戏在哪个平面上进行。如果你在XY平面上移动物体,我想应该可以。但在某些情况下,Atan2将0返回到-Pi这一事实可能会影响您。要解决此问题:if(targetRotation<0f)targetRotation=MathHelper.TwoPi-targetRotation;尽管如此。穿越0时可能会遇到一些问题。。。隐马尔可夫模型。。
public float rotX { get; set; }
public float rotY { get; set; }
public Vector3 position { get; set; }
public Matrix Transform {
get {
return (Matrix.Identity *
Matrix.CreateScale(scale) *
Matrix.CreateRotationY(MathHelper.Pi) *
Rotation *
Matrix.CreateTranslation(position));
}
}
public float ShipCurRotation { get { return (rotX + MathHelper.ToRadians(currentRotation)); } }
public Matrix Rotation { get { return (Matrix.CreateRotationY(ShipCurRotation) * Matrix.CreateRotationX(rotY)); } }
public void MoveToPosition(Vector3 pos) {
desiredRotation = (CalculateAngleFromVectors(position, pos) - MathHelper.ToDegrees(rotX));
isMoving = true;
}