顺时针或逆时针 Lerp 旋转角度

Lerp rotation angles clock or counter-clockwise

我正在尝试找到允许您指定方向(顺时针或逆时针)的角度 lerp(线性插值)的实现。我发现的大多数实现都依赖于可能的最短路径,例如:

https://gist.github.com/shaunlebron/8832585

我想要这样的功能:

// from        = angle where to start
// to          = target angle
// direction   = wether to reach "to" clock or counter clock wise
// progress    = 0-1 progress range 0 = from value 1 = to value.

function angle_lerp(from, to, direction, progress) {}

这里有几个例子可以进一步阐明函数的预期行为。所有示例均基于 0-360 度范围:

# clockwise (short path)
angle_lerp(from=350, to=10, direction=clockwise, progress=0) = 350
angle_lerp(from=350, to=10, direction=clockwise, progress=0.5) = 0
angle_lerp(from=350, to=10, direction=clockwise, progress=1) = 10

# counter-clockwise (long path)
angle_lerp(from=350, to=10, direction=counter, progress=0) = 350
angle_lerp(from=350, to=10, direction=counter, progress=0.5) = 180
angle_lerp(from=350, to=10, direction=counter, progress=1) = 10
# clockwise (short path)
angle_lerp(from=90, to=180, direction=clockwise, progress=0.33333) = 119.7
angle_lerp(from=90, to=180, direction=clockwise, progress=0.5) = 135
angle_lerp(from=90, to=180, direction=clockwise, progress=0.8) = 162 

# counter (long path)
angle_lerp(from=90, to=180, direction=counter, progress=0.33333) = 0
angle_lerp(from=90, to=180, direction=counter, progress=0.66666) = 270

示例,其中 fromto 的“超前”:

# clockwise (long path)
angle_lerp(from=45, to=0, direction=clockwise, progress=0.1) = 76.5
angle_lerp(from=45, to=0, direction=clockwise, progress=0.5) = 202.5
angle_lerp(from=45, to=0, direction=clockwise, progress=0.95) = 344.25

# counter (short route)
angle_lerp(from=45, to=0, direction=counter, progress=0.1) = 40.5
angle_lerp(from=45, to=0, direction=counter, progress=0.5) = 22.5
angle_lerp(from=45, to=0, direction=counter, progress=0.95) = 2.25

假设通常的约定(角度在逆时针方向增加),这是一个PHP解决方案。

$from$to 是归一化角度(在 0 和 360 之间)。
$cw 是一个布尔值(true 顺时针,false 逆时针)。
$progress 介于 0 和 1 之间。

function angle_lerp($from, $to, $cw, $progress)
{
    if($cw)
    {
        // Clockwise
        if($from < $to)
            $to -= 360;
    }
    else
    {
        // Counter-clockwise
        if($from > $to)
            $to += 360;
    }
    return $from + ($to-$from)*$progress;
}

示例:

echo angle_lerp(350, 10, true, 0.5); // 180
echo angle_lerp(350, 10, false, 0.5); // 360