旋转-查找何时达到所需角度 [英] Rotation - Finding when desired angle is reached

查看:83
本文介绍了旋转-查找何时达到所需角度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

情况

我已经在这个问题上打了一段时间了.基本上,我有一个角度 r (弧度),我想更改为所需的角度 wr (弧度),并在仿真的每个步骤中以设置的速度 dr (弧度/秒).因此,我需要为每个步骤设置一个新的角度 nr ,其中 nr = r + dr * dt ,而 dt 是变化时间从最后一步开始.

I've been hitting my head on this problem for a while now. Basically, I have an angle r (radians), that I want to change to a desired angle wr (radians) with a set speed dr (radians / second), during each step of a simulation. Thus I need that for each step, I have a new angle nr, where nr = r + dr * dt and dt is the delta time since the last step.

角在空间[-pi,pi]中,而δ角由最短的转弯方式确定.对于每一步,将增量角度添加到当前旋转中,并包装为[-pi,pi]并存储为新角度.

Angles are in the space [-pi, pi] and the delta angle is determined by the shortest way to turn. For each step, the delta angle is added to the current rotation, wrapped to [-pi, pi] and stored as the new angle.

由于我的步伐并没有无限的精度,我显然-实际上-永远不会一直直击所需的角度,因此我需要找到何时达到所需的旋转-并交叉-然后停止旋转并将角度设置为所需角度.用伪代码:

Since I haven't got infinite precision in my steps, I will obviously - virtually - never hit the desired angle straight on, thus I need to find when the desired rotation has been reached - and crossed - and then stop rotating and set the angle to the desired angle. In pseudocode:

if rotationSpeed!= 0
     angle = WrapRotation(angle + rotationSpeed * deltaTime)
     if desiredAngle has been reached or crossed
       angle = desiredAngle
       rotationSpeed = 0

问题

在几乎所有情况下,这都很容易做到,但是当您有一个足够高或低的角度(接近-pi或pi)并且新角度将您带入边界"时,可以这么说复杂.我的所有尝试都未能涵盖当前,先前和所需轮换的所有可能情况.所以我问你是否碰巧知道一个解决方案?

In almost all circumstances, this is easy to do, but when you have an angle high or low enough (close to -pi or pi) and the new angle takes you across the "border", so to speak, things get complicated. All of my attempts have failed to cover all possible situations on current, previous and desired rotation. So I'm asking you if you happen to know a solution for this?

如果需要,我在下面附加了我的代码(C#):

If needed, I've attached my code (C#) below:

// Sets the desired rotation and rotation speed in radians/second:
public void SetRotation(float rotation, float speed)
{
        desiredRotation = MathHelper.WrapAngle(rotation);
        if (desiredRotation != this.rotation)
        {
            // Determine the shortest way to turn (indicated by the sign of speed)
            float a = desiredRotation - this.rotation;
            if (a > Math.PI) a -= 2 * (float)Math.PI;
            if (a < -Math.PI) a += 2 * (float)Math.PI;

            desiredRotationSpeed = a < 0 ? -speed : speed;
        }
 }

 // Update is called per each step. Takes in the amount of seconds since the last call.
 public void Update(float seconds)
 {
        /* Other stuff */
        if (desiredRotationSpeed != 0)
        {
            float delta = desiredRotationSpeed * seconds;
            rotation = MathHelper.WrapAngle(rotation + delta);
            if( /* This is the part I'm struggling with. */ )
            {
                desiredRotationSpeed = 0f;
                rotation = desiredRotation;
            }
        }
        /* Other stuff */
 }

在正常情况下(非循环行为),以下作品:

Under normal circumstances (non-cylic behaviour) the following works:

if (Math.Abs(value - desiredValue) < Math.Abs(deltaValue))
    /* Desired has been reached. Do stuff! */

因此请澄清.我想查找何时击中了所需角度(由于精度而超过了该角度),以便可以将当前角度设置为所需角度,然后停止旋转.

So to clarify. I want to find when the desired angle has been hit (and surpassed due to the precision), so that I can set my current angle to the desired, and stop rotating.

非常感谢您的帮助!我觉得这真的有一个简单的解决方案! :3

Thanks a lot for your help! I have a feeling that this really has a simple solution! :3

推荐答案

您为什么交叉所需的轮换?为什么不以当前角度与所需角度之间的最小角度以及您要移动的增量来计算增量?这样,最后一步将您精确地移动到所需的角度.

Why do you cross the desired rotation? Why not calculate the delta as the minimum of the angle between the current angle and the desired angle and the delta you'd like to move? That way the last step moves you to exactly the desired angle.

我还将更改您的代码,以便SetRotation除了存储两个值desiredRotationspeed之外什么都不做,然后Update中的计算可以将所需角度与当前角度进行比较,计算出差值,将其限制为速度值x秒数,然后再移动该数量(使用+ ve或-ve方向的适当if语句).

I would also change your code so that SetRotation does nothing but store the two values desiredRotation and speed and then the calculation in Update can compare the desired angle with the current angle, calculate the difference, limit that to the speed value x the number of seconds and then move by that amount (with the appropriate if statement for the direction +ve or -ve).

这篇关于旋转-查找何时达到所需角度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆