如何随着时间的推移旋转到目标位置

我知道如何做向量的旋转,但随着时间的推移如何旋转?

比如说我做了一个function

RotateTo(vec2 iPosition, float iTime); 

所以它旋转到iTime iPosition – 这将如何看? 有谁知道简单的algorithm?

Solutions Collecting From Web of "如何随着时间的推移旋转到目标位置"

如果你在三维空间,它真的取决于你想要旋转的轴。 当你不告诉你的函数应该在哪里旋转时,有无限的可能性。 目前的function签名似乎有两种可能性:

  • 你在二维空间旋转
  • 你总是想旋转最小的距离

我只能给你一个关于旋转如何完成的理论概述。 因为它似乎真正的游戏编程使用其他方法(请参阅下面的其他答案和评论我的文字)。 不过,我想这还是个好消息,因为这是旋转的第一个原则。

随着时间的推移旋转

随着时间的推移,只是每个时间步的部分旋转。 你必须找出你想要旋转的时间段以及自上次旋转以来的时间。 这将需要至less3个variables:

  • 旋转时间
  • 自上次部分旋转以来的经过时间
  • 旋转角度

当然,我们也需要vector当前的位置:

  • vector位置

现在有两种可能性(当使用旋转matrix时)。 据我所知,四元数会更好,因为在进行许多小的旋转时,他们不会遭受那么多的错误。 然而我认为,还有一种方法是用matrix来最小化这种方法。

现在有不同的方法。 那些我看到的:

  • 真正使用自上次旋转以来的时间,并按角度/ n度旋转n次
  • 记住从你开始开始的时间,并从那里做旋转。 这将消除错误,因为最终的位置将像原来的位置一样旋转。

我们来描述第二种方法。

你需要有一个方法,需要:

  • 原始的vector位置
  • 目标角度
  • 时间旋转
  • 旋转开始后的经过时间

那么你可以简单地按照下面的公式旋转:

 function rotateOverTime(vector, angle, timespan, elapsedTimeSinceStart): partialAngle = elapsedTimeSinceStart / timespan * angle; rotateZ(vector, partialAngle); 

请注意,使用此方法vector将始终是原始vector (不考虑部分旋转),并且elapsedTimeSinceStart是自所有旋转开始以来的时间

另一种方法是使用新的vector位置和自上次旋转以来的时间,但是随后您将从小旋转累积误差,并且旋转不再是一个不错的圆。

在二维空间旋转

如果你想在二维空间旋转,你实际上围绕Z轴旋转(因为你在X轴和Y轴上绘制)。 如果您的库已经实现了RotateZfunction,您可以使用它。 否则,你可以使用sincos

我不清楚它的细节,但它应该类似于这个。 可能这不是最快最优雅的解决scheme:

  • 计算vector的当前角度。 这可以用atan2()来完成
  • 你想旋转的点通常不是(0,0),所以你必须移动你的东西, 看起来像是这样(如果旋转中心是例如(10,10)你必须减去10 ,从旋转的角度看10个)
  • 乘以新的点(=向量;我将在以后使用,因为在代数中,你总是谈论向量)与旋转matrix。 我将在后面更详细地展示这是什么。
  • 通过添加之前扣除的金额(这里是10),将您的点移到旧的位置。

我希望这些图像能让我的math说得更清楚一些)

我们想要像(绿色)圆圈所示的那样围绕(1,2)旋转点(5,5)。 但是在matrix中,我们会像紫色圆圈一样旋转(0,0)。

我们想要实现旋转,但是会出现什么问题

为了解决这个问题,我们把我们的观点左移一下,然后我们可以把它旋转(0,0),然后再移回去。 这个移动被称为翻译 。 其实我的形象在这里有点吸引力,向上的紫色箭头应该和第一个紫色箭头一样的对角线。 请记住,我们先移动我们的点(-1,-2),然后再移动(1,2)。 所以我的箭头不太好。

我们如何解决它

我谈到了旋转matrix 。 一个旋转matrix是一个matrix,你可以乘你的向量来实现围绕原点(0,0)的旋转。

 cos a -sin a sin a cos a 

其中a是要旋转的所需角度。 这个角度是由菲利普已经显示的帧数决定的。 例如,如果您希望它在2秒内旋转90° ,此后1秒钟过去,则将其旋转总旋转的1/2(= 45°)。

在这种情况下,你的旋转matrix看起来像这样:

 cos 45° -sin 45° sin 45° cos 45° 

给定这个matrix,你可以乘以你当前的vector来旋转它。

让我们想象你的vector是(5,7)。 这会让你(-1.414,8.485)逆时针旋转45°。

如果你需要顺时针旋转,你可以调整旋转matrix。 通过从360减去你的旋转(例如,顺时针旋转15°逆时针旋转365°),或者通过使用三角规则。

让我提一下,这总是围绕原点旋转。 通常你不想在游戏中围绕原点旋转,因为原点是一些随机点。 在2D编程中,它通常是整个世界或当前视口(相机)的左上角点。 图书馆中的更高层次的抽象通常使用图片的起源 (左上角),但这也不是经常需要的。

我们能做些什么呢? 这里的magic关键字是翻译 ,它意味着移动一个对象。 旋转时,必须确保将物体移动到所需的位置以便旋转,之后可以将其移回。

想象一下,在(200,300)世界坐标下,2D中有一个点。 现在你想旋转(250,250)50°。 如果你只是将(200,300)乘以旋转matrix(你将设置一个= 50°),那么这个点就是屏幕的全部。 相反,移动你的点,使(250,250)等于(0,0)。 我们会得到我们当前的点(200-250,300-250)=(-50,50)。 现在你可以旋转这个! 旋转之后,再次移动新的点(+250)。

在3D空间中旋转

在3D空间中,您可以围绕无限数量的轴旋转,以达到给定其他点的一个点。 但是,轮换并不总是最短的。 这可能需要一些时间来理解,但只要用左手和右手食指作为空间点。 现在你可以向上翻转,向下翻转,向前翻…

因此,我们总是需要知道当我们在3D中的哪个轴转动。 一般来说,你有绕X,Y和Z轴的基本旋转。 还记得我们用二维的Z轴。

也许你记得我提到了从顶端到最短距离的一些事情。 实际上,我不完全确定这是否正确,但是我想我记得我的线性代数类中的一些东西。 根据我现在的想法,在3D旋转时总是应该有最短的距离。 只有当两个向量都不是独立的时候,又有不确定数量的最短距离,但是现在让我们忘记这个。

所以如果你没有一个坐标轴,但是想确定一个坐标轴,你可以这样做:

  • 计算两个vector(点)的叉积=>结果是一个与两个vector无关的vector。
  • 围绕新的vector作为轴旋转。 这会给你最短的旋转距离。
  • 测量两个vector之间的角度(围绕计算轴)。 现在还不能告诉你这个怎么做,但这不是一个很难的计算,你只需要知道如何^ _ ^
  • 规范化这个向量(长度= 1)
  • 移动你的整个场景,让你想要旋转的点是原点(0,0,0)
  • 使用一个公式来旋转绕轴和三维角度
  • 将你的(旋转的)场景移回原来的位置

希望我能以某种方式帮助你,因为这对我来说似乎相当困难,但我想详细解释如何旋转作品。

假设你想让它在一秒钟内旋转360度。

我们还要说,iTime决定了函数被调用后的秒数。 所以如果iTime是.01,那么自上次函数被调用以来已经过了1/100秒。

然后你会使用iTime / 360来计算你需要应用多less轮换。

正如其他人所指出的,你实在没有足够的信息去做你想做的事情。 你需要一个轴旋转,开始角度和结束角度。

然而,考虑到所有这一切,你想要看什么是斯勒普 。 大多数API和引擎将提供实现所需的调用,并构建您想要实现的调用,但是在问题中没有提供足够的信息来指向任何特定的资源。