旋转插补

发布于 2024-08-30 01:13:38 字数 464 浏览 5 评论 0原文

注意:为了简单起见,我将用度数来提出这个问题,弧度,度数,不同的零轴承,问题本质上是相同的。

有人对旋转插值背后的代码有什么想法吗?给定一个线性插值函数:Lerp(from, to, amount),其中 amount 是 0...1,它按 amount 返回一个介于 from 和 to 之间的值。如何将相同的函数应用于 0 到 360 度之间的旋转插值?鉴于度数不应在 0 和 360 之外返回。

给定度数单位圆:

Unit Circle

其中 from = 45 且to = 315,算法应该采用到达角度的最短路径,即它应该经过零,到360,然后到315 - 而不是一直绕90、180、270到315。

有没有一个好的方法来实现这?或者它只是一堆可怕的 if() 块?我是否缺少一些众所周知的标准方法? 任何帮助将不胜感激。

NB: I'll present this question in degrees purely for simplicity, radians, degrees, different zero-bearing, the problem is essentially the same.

Does anyone have any ideas on the code behind rotational interpolation? Given a linear interpolation function: Lerp(from, to, amount), where amount is 0...1 which returns a value between from and to, by amount. How could I apply this same function to a rotational interpolation between 0 and 360 degrees? Given that degrees should not be returned outside 0 and 360.

Given this unit circle for degrees:

Unit Circle

where from = 45 and to = 315, the algorithm should take the shortest path to the angle, i.e. it should go through zero, to 360 and then to 315 - and not all the way round 90, 180, 270 to 315.

Is there a nice way to achieve this? Or is it going to just be a horrid mess of if() blocks? Am I missing some well understood standard way of doing this?
Any help would be appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(10

对岸观火 2024-09-06 01:13:38

我知道这已经有 2 年历史了,但我最近一直在寻找同样的问题,并且我没有看到没有在这里发布 ifs 的优雅解决方案,所以这里是:

    shortest_angle=((((end - start) % 360) + 540) % 360) - 180;
    return shortest_angle * amount;

就是这样

ps:当然,% 的意思modulo 和shortest_angle 是保存整个插值角度的变量

I know this is 2 years old, but I've recently been looking around for the same problem and I don't see an elegant solution without ifs posted in here, so here it goes:

    shortest_angle=((((end - start) % 360) + 540) % 360) - 180;
    return shortest_angle * amount;

that's it

ps: of course, % is meaning modulo and shortest_angle is the variable that holds the whole interpolation angle

芸娘子的小脾气 2024-09-06 01:13:38

抱歉,这有点复杂,这是一个更简洁的版本:

    public static float LerpDegrees(float start, float end, float amount)
    {
        float difference = Math.Abs(end - start);
        if (difference > 180)
        {
            // We need to add on to one of the values.
            if (end > start)
            {
                // We'll add it on to start...
                start += 360;
            }
            else
            {
                // Add it on to end.
                end += 360;
            }
        }

        // Interpolate it.
        float value = (start + ((end - start) * amount));

        // Wrap it..
        float rangeZero = 360;

        if (value >= 0 && value <= 360)
            return value;

        return (value % rangeZero);
    }

有人有更优化的版本吗?

Sorry, that was a bit convoluted, here's a more concise version:

    public static float LerpDegrees(float start, float end, float amount)
    {
        float difference = Math.Abs(end - start);
        if (difference > 180)
        {
            // We need to add on to one of the values.
            if (end > start)
            {
                // We'll add it on to start...
                start += 360;
            }
            else
            {
                // Add it on to end.
                end += 360;
            }
        }

        // Interpolate it.
        float value = (start + ((end - start) * amount));

        // Wrap it..
        float rangeZero = 360;

        if (value >= 0 && value <= 360)
            return value;

        return (value % rangeZero);
    }

Anyone got a more optimised version?

仅此而已 2024-09-06 01:13:38

我认为更好的方法是插入正弦和余弦,因为它们不会受到多重定义的影响。令 w =“数量”,以便 w = 0 为角度 A,w = 1 为角度 B。然后

CS = (1-w)*cos(A) + w*cos(B);
SN = (1-w)*sin(A) + w*sin(B);
C = atan2(SN,CS);

One 必须根据需要转换为弧度和度数。还得调整分支。对于atan2 C 回到-pi 到pi 的范围内。如果你想要 0 到 2pi 那么只需将 pi 添加到 C 即可。

I think a better approach is to interpolate sin and cos since they don't suffer form being multiply defined. Let w = "amount" so that w = 0 is angle A and w = 1 is angle B. Then

CS = (1-w)*cos(A) + w*cos(B);
SN = (1-w)*sin(A) + w*sin(B);
C = atan2(SN,CS);

One has to convert to radians and degrees as needed. One also has to adjust the branch. For atan2 C comes back in the range -pi to pi. If you want 0 to 2pi then just add pi to C.

呆橘 2024-09-06 01:13:38

注意:使用 C# 代码

在我的大脑中进行了一些疯狂的翻查之后,这就是我想到的。
基本上前提是在最后一刻执行0-360 环绕。在内部处理 0-360 之外的值,然后在函数请求值时将它们包装在 0-360 内。

在选择起点和终点时,执行以下操作:

float difference = Math.Abs(end - start);
if (difference > 180)
{
    // We need to add on to one of the values.
    if (end > start)
    {
        // We'll add it on to start...
        start += 360;
    }
    else
    {
        // Add it on to end.
        end += 360;
    }
}

这将为您提供实际的起点和终点值,该值可能在 0-360 范围之外...

我们有一个换行函数来确保值在 0 之间和 360...

public static float Wrap(float value, float lower, float upper)
{
    float rangeZero = upper - lower;

    if (value >= lower && value <= upper)
        return value;

    return (value % rangeZero) + lower;
}

然后,当您从函数请求当前值时:

return Wrap(Lerp(start, end, amount), 0, 360);

这几乎肯定不是问题的最佳解决方案,但它似乎始终有效。如果有人有任何更优化的方法来做到这一点,那就太好了。

NB: using C# code

After some crazy rummaging around in my brain, here's what I've come up with.
Basically the premise is to perform the 0-360 wrapping at the last minute. Deal internally with values outside 0-360 and then wrap them inside 0-360 at the point a value is requested from the function.

At the point where you pick a start an an end point, you perform the following:

float difference = Math.Abs(end - start);
if (difference > 180)
{
    // We need to add on to one of the values.
    if (end > start)
    {
        // We'll add it on to start...
        start += 360;
    }
    else
    {
        // Add it on to end.
        end += 360;
    }
}

This gives you the actual start and end values, which may be outside 0-360...

We have a wrap function to ensure a value is between 0 and 360...

public static float Wrap(float value, float lower, float upper)
{
    float rangeZero = upper - lower;

    if (value >= lower && value <= upper)
        return value;

    return (value % rangeZero) + lower;
}

Then at the point you request the current value from the function:

return Wrap(Lerp(start, end, amount), 0, 360);

This is almost certainly not the most optimal solution to the problem, however it does appear to work consistently. If anyone has any more optimal way to do this that would be great.

┈┾☆殇 2024-09-06 01:13:38

我想重写我的答案以更好地解释回答问题。我使用 EXCEL 作为公式,使用度数作为单位。

为简单起见,B 是两个值中较大的一个,A 是两个值中较小的一个。您稍后可以在解决方案中分别使用 MAX()MIN()

第 1 部分 - 走哪条路?

我们首先要做的是弄清楚我们想要执行计算的方向,顺时针还是逆时针。为此,我们使用 IF() 语句:

IF( (B-A)<=180, (Clockwise_Formula), (AntiClockwise_Formula) )

上面的公式检查是否从 B 逆时针移动到 A(这与顺时针移动相同)从 AB)小于或等于 180 度。如果没有的话,走另一个方向会更短。

要检查其是否有效:90 - 45 = 45(小于或等于 180)使 IF 语句为 TRUE,因此顺时针方向较短,但 315 - 45 = 270(大于 180)使 if 语句成立FALSE,因此逆时针公式会更短。

第 2 部分 - 顺时针公式

现在您想要在 AB 之间顺时针或逆时针插值 N 次。顺时针方向的公式比较简单。

Clockwise_Formula: ((B-A)/N*S)+A

其中 S 是插值次数的计数,从 1 开始,到 N-1 结束(如果 S = N,您的答案将为 B code>)

示例:A = 90,B = 270,N = 4

S=1:     ((270-90)/4*1)+90 = 135
S=2:     ((270-90)/4*2)+90 = 180
S=3:     ((270-90)/4*3)+90 = 225

第 3 部分 - ANITCLOCKWISE公式 逆时针公式会稍微复杂一些,因为我们需要逆时针穿过 360 度角。我能想到的最简单的方法是将 360 添加到 A,然后使用 MOD(FORMULA,VALUE) 函数将答案调制 360。

您还必须在公式中交换 AB,因为 B 现在是最小的数字。 (这可能听起来有点令人困惑,但它确实有效!)

(Unmodulated) AntiClockwise_Formula: (((A+360)-B)/N*S)+B

示例:A = 60、B = 300、N = 4

S=1:     (((60+360)-300)/4*1)+300 = 330
S=2:     (((60+360)-300)/4*2)+300 = 360
S=3:     (((60+360)-300)/4*3)+300 = 390

第 4 部分 - 将答案限制在 0 到 360 之间

看看有时(但并非总是)答案会大于 360 吗?这就是将逆时针公式包装在 MOD() 函数中的用处:

AntiClockwise_Formula: MOD((((A+360)-B)/N*S)+B,360)

调整第 3 部分中使用的示例将为您提供:

S=1:     330
S=2:     0
S=3:     30

第 5 部分 - 将所有内容组合在一起

将第 1-4 部分中的元素加在一起,答案为:

IF((B-A)<=180,((B-A)/N*S)+A,MOD((((A+360)-B)/N*S)+B,360))

其中:

A = 两个值中较小的一个(您可以用 MIN() 替换 A)

B =两个值中较大的一个(您可以用 MAX() 替换 B)

N = 您想要执行的插值次数(例如 2 是二分之一,3 是三分之一等)

S = 最大 N-1 的增量计数(请参阅第 2 部分了解解释)

I wanted to rewrite my answer to better explain answer the question. I'm using EXCEL for my formulas, and degrees for my units.

For simplicity, B is the larger of the two values, and A is the smaller of the two values. You can use MAX() and MIN() respectively in your solution later.

PART 1 - WHICH WAY TO GO?

What we want to do first is work out in which direction we want to perform the calculation, clockwise or anticlockwise. We use an IF() Statement for that:

IF( (B-A)<=180, (Clockwise_Formula), (AntiClockwise_Formula) )

The above formula checks if going anticlockwise from B to A (which is the same as going clockwise from A to B) is less than or equal to 180 degrees. If not, it's going to be shorter to go the other direction.

To check this works: 90 - 45 = 45 (which is less than or equal to 180) makes the IF statement TRUE, so the clockwise direction is shorter, but 315 - 45 = 270 (which is larger than 180) makes the if statement FALSE, so the anticlockwise formula would be shorter.

PART 2 - CLOCKWISE FORMULA

Now you want to interpolate N times between A and B, either clockwise or anticlockwise. The clockwise formula is relatively simple.

Clockwise_Formula: ((B-A)/N*S)+A

Where S is a count of the number of interpolations, starting at 1 and finishing at N-1 (If S = N, your answer will be B)

Example: A = 90, B = 270, N = 4

S=1:     ((270-90)/4*1)+90 = 135
S=2:     ((270-90)/4*2)+90 = 180
S=3:     ((270-90)/4*3)+90 = 225

PART 3 - ANITCLOCKWISE FORMULA

The anitclockwise formula is going to be a little more complex, because we'll need to cross anticlockwise over the 360 degree angle. The easiest method I can think of is to add 360 to A, then Modulate the answer by 360 using the MOD(FORMULA,VALUE) function.

You'll also have to swap A and B around in the formula because B is now the smallest number. (That might sound a bit confusing, but it works!)

(Unmodulated) AntiClockwise_Formula: (((A+360)-B)/N*S)+B

Example: A = 60, B = 300, N = 4

S=1:     (((60+360)-300)/4*1)+300 = 330
S=2:     (((60+360)-300)/4*2)+300 = 360
S=3:     (((60+360)-300)/4*3)+300 = 390

PART 4 - RESTRICTING ANSWERS TO BETWEEN 0 AND 360

See how sometimes (but not always) the answers are going to be greater than 360? This is where the wrapping your Anticlockwise_formula in a MOD() function comes in:

AntiClockwise_Formula: MOD((((A+360)-B)/N*S)+B,360)

Modulating the example used in Part 3 will give you:

S=1:     330
S=2:     0
S=3:     30

PART 5 - PUTTING IT ALL TOGETHER

Combining all of the elements from Parts 1-4 together, the answer is:

IF((B-A)<=180,((B-A)/N*S)+A,MOD((((A+360)-B)/N*S)+B,360))

Where:

A = The smaller of the two values (you can replace A with MIN())

B = The larger of the two values (you can replace B with MAX())

N = The number of interpolations you want to do (e.g. 2 is a half, 3 is into thirds etc)

S = An incrimental count to a max of N-1 (see Part 2 for explanation)

何处潇湘 2024-09-06 01:13:38

我处理角度的首选方法是使用每转 2 的幂的单位。例如,如果您使用 16 位有符号整数来表示 -180 到 +180 度,您可以简单地采用 (from-to)/num_steps 来进行插值。添加和减去角度总是有效的,因为二进制值会在从 360 到 0 的位置溢出。

在您的情况下,您可能想要做的是数学模 360。因此,角度差计算为 (from-to)% 360.仍然存在一些标志问题,这些问题已在其他 SO 问题中得到解决。

My preferred way to deal with angle is to use units that are a power of 2 per revolution. For exanple, it you use 16 bit signed integers to represent -180 to +180 degrees, you can simply take (from-to)/num_steps to do your interpolation. Adding and subtracting angles always works, as the binary values overflow right at the point where you go from 360 to 0.

What you probably want to do in your case is math modulo 360. So angle differences are computed as (from-to)%360. There are still some sign issues with that which have been addressed in other SO questions.

债姬 2024-09-06 01:13:38

修改 user151496 的答案(原始版本以度为单位,也给了我错误的输出):

 def interp_angle(theta_1, theta_2, ratio):
    shortest_angle = ((((theta_2 - theta_1) % (np.pi*2)) + np.pi) % (np.pi*2)) - np.pi
    return (theta_1 + shortest_angle * ratio) % (np.pi*2)

测试:运行

theta1, theta2 = 0, 0.5
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 0.99
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 1.01
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, -0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, 2-0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))

给我:

Average of 0pi rad and 0.5pi rad = 0.25pi rad
Average of 0pi rad and 0.99pi rad = 0.495pi rad
Average of 0pi rad and 1.01pi rad = 1.505pi rad
Average of 0.1pi rad and -0.1pi rad = 0pi rad
Average of 0.1pi rad and 1.9pi rad = 0pi rad

Modification of user151496 's answer (the original was in degrees and also giving me a wrong output):

 def interp_angle(theta_1, theta_2, ratio):
    shortest_angle = ((((theta_2 - theta_1) % (np.pi*2)) + np.pi) % (np.pi*2)) - np.pi
    return (theta_1 + shortest_angle * ratio) % (np.pi*2)

Tests: Running with

theta1, theta2 = 0, 0.5
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 0.99
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0, 1.01
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, -0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))
theta1, theta2 = 0.1, 2-0.1
print('Average of {:.4g}pi rad and {:.4g}pi rad = {:.4g}pi rad'.format(theta1, theta2, interp_angle(theta1*np.pi, theta2*np.pi, 0.5)/np.pi))

Gives me:

Average of 0pi rad and 0.5pi rad = 0.25pi rad
Average of 0pi rad and 0.99pi rad = 0.495pi rad
Average of 0pi rad and 1.01pi rad = 1.505pi rad
Average of 0.1pi rad and -0.1pi rad = 0pi rad
Average of 0.1pi rad and 1.9pi rad = 0pi rad
小鸟爱天空丶 2024-09-06 01:13:38

对于这个问题,如果角度在 +-pi 范围内,请使用以下命令:
((结束 - 开始 + pi)%tau + tau)%tau - pi

For this problem, if you have angles in the range +-pi use this:
((end - start + pi)%tau + tau)%tau - pi

旧时光的容颜 2024-09-06 01:13:38

我个人的建议?:不要!与欧拉角的 3d 旋转类似,我发现使用更高维度的抽象更不容易出错并且更容易实现。在这种情况下,不用四元数,只需使用一个简单的二维向量,对向量执行线性插值(一个简单且明确的操作),然后使用 atan2 来获取角度!像这样的:

     Vector2 interop=lerp(v1,v2);
     float angle=atan2(interop.x,interop.y);

其中 v1, v2 是指向单位圆上不同点的两个向量,而 lerp() 只是平均线性插值函数。根据您的环境,您可能有权也可能无法访问向量类,但假设您有基本的数学背景,那么基础知识的实现就非常简单(如果您不介意的话,还有大量的库!) 。作为额外的好处,您可以轻松更改插值类型,而不会弄乱任何额外条件等...

PS
我对回答有关 SO 的问题相当陌生,所以我不确定通过引导某人使用完全不同的方法来回答问题是否可以接受。我见过这样做,但有时会遭到反对......

My personal recommendation?: Don't! Similar to 3d rotation with Euler angles , I find that using a higher dimension abstraction far less error prone and much easier to implement. In this case, instead of Quaternions, just use a simple 2 dimensional vector, perform the linear interpolation on the vector ( a trivial and unambiguous operation), and then use atan2 to get the angle! Something like this:

     Vector2 interop=lerp(v1,v2);
     float angle=atan2(interop.x,interop.y);

Where v1, v2 are two vectors pointing to different points on a unit circle and lerp() is just your average linear interpolation function. Depending upon your environment, you may or may not have access to vector classes, but assuming you have even a rudimentary background in math, the basics are very trivial to implement (and there are tons of libraries if you can't be bothered!). As an added bonus, you can trivially change the type of interpolation without messing with any extra conditions etc...

P.S.
I'm reasonably new to answering questions on SO , so I'm not sure if it's acceptable to answer a question by directing someone to a completely different method. I've seen it done, but it sometimes receive opposition...

自控 2024-09-06 01:13:38

我对度数的解决方案。在我的 VarTracker 课程中

    @classmethod
def shortest_angle(cls, start: float, end: float, amount: float):
    """ Find shortest angle change around circle from start to end, the return
        fractional part by amount.
    VarTracker.shortest_angle(10, 30, 0.1) --> 2.0
    VarTracker.shortest_angle(30, 10, 0.1) --> -2.0
    VarTracker.shortest_angle(350, 30, 0.1) --> 4.0
    VarTracker.shortest_angle(350, 30, 0.8) --> 32.0
    VarTracker.shortest_angle(30, 350, 0.5) --> -20.0
    VarTracker.shortest_angle(170, 190, 0.1) --> 2.0
    VarTracker.shortest_angle(10, 310, 0.5) --> -30.0
    """
    sa = ((((end - start) % 360) + 540) % 360) - 180;
    return sa * amount;

@classmethod
def slerp(cls, current: float, target: float, amount: float):
    """ Return the new value if spherical linear interpolation from current toward target, by amount, all in degrees.
    This method uses abs(amount) so sign of amount is ignored.
    current and target determine the direction of the lerp.
    Wraps around 360 to 0 correctly.

    Lerp from 10 degrees toward 30 degrees by 3 degrees
    VarTracker.slerp(10, 30, 3.0) --> 13.0
    Ignores sign of amount
    VarTracker.slerp(10, 30, -3.0) --> 13.0
    VarTracker.slerp(30, 10, 3.0) --> 27.0
    Wraps around 360 correctly
    VarTracker.slerp(350, 30, 6) --> 356.0
    VarTracker.slerp(350, 30, 12) --> 2.0
    VarTracker.slerp(30, 350, -35) --> 355.0
    a = VarTracker.slerp(30, 3140, -35) --> 355.0
    VarTracker.slerp(170, 190, 2) --> 172.0
    VarTracker.slerp(10, 310, 12) --> 358.0
    Wraps over 0 degrees correctly
    VarTracker.slerp(-10, 10, 3) --> 353.0
    VarTracker.slerp(10, -10, 12) --> 358
    """
    a = VarTracker.shortest_angle(current, target, 1.0)
    diff = target - current
    if np.abs(amount) > np.abs(diff):
        amount = diff
    if a < 0:
        amount = -np.abs(amount)
    else:
        amount = np.abs(amount)
    ret = current + amount
    while ret < 0:
        ret = ret + 360
    ret = ret % 360
    return ret

My solution to slerp of degrees. In my VarTracker class

    @classmethod
def shortest_angle(cls, start: float, end: float, amount: float):
    """ Find shortest angle change around circle from start to end, the return
        fractional part by amount.
    VarTracker.shortest_angle(10, 30, 0.1) --> 2.0
    VarTracker.shortest_angle(30, 10, 0.1) --> -2.0
    VarTracker.shortest_angle(350, 30, 0.1) --> 4.0
    VarTracker.shortest_angle(350, 30, 0.8) --> 32.0
    VarTracker.shortest_angle(30, 350, 0.5) --> -20.0
    VarTracker.shortest_angle(170, 190, 0.1) --> 2.0
    VarTracker.shortest_angle(10, 310, 0.5) --> -30.0
    """
    sa = ((((end - start) % 360) + 540) % 360) - 180;
    return sa * amount;

@classmethod
def slerp(cls, current: float, target: float, amount: float):
    """ Return the new value if spherical linear interpolation from current toward target, by amount, all in degrees.
    This method uses abs(amount) so sign of amount is ignored.
    current and target determine the direction of the lerp.
    Wraps around 360 to 0 correctly.

    Lerp from 10 degrees toward 30 degrees by 3 degrees
    VarTracker.slerp(10, 30, 3.0) --> 13.0
    Ignores sign of amount
    VarTracker.slerp(10, 30, -3.0) --> 13.0
    VarTracker.slerp(30, 10, 3.0) --> 27.0
    Wraps around 360 correctly
    VarTracker.slerp(350, 30, 6) --> 356.0
    VarTracker.slerp(350, 30, 12) --> 2.0
    VarTracker.slerp(30, 350, -35) --> 355.0
    a = VarTracker.slerp(30, 3140, -35) --> 355.0
    VarTracker.slerp(170, 190, 2) --> 172.0
    VarTracker.slerp(10, 310, 12) --> 358.0
    Wraps over 0 degrees correctly
    VarTracker.slerp(-10, 10, 3) --> 353.0
    VarTracker.slerp(10, -10, 12) --> 358
    """
    a = VarTracker.shortest_angle(current, target, 1.0)
    diff = target - current
    if np.abs(amount) > np.abs(diff):
        amount = diff
    if a < 0:
        amount = -np.abs(amount)
    else:
        amount = np.abs(amount)
    ret = current + amount
    while ret < 0:
        ret = ret + 360
    ret = ret % 360
    return ret
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文