限制范围内浮动角度的快速方法是什么?

时间:2017-08-30 08:56:26

标签: math

例如,我有一个值为350度的角度,我想在最大正偏移为30且最大负偏移为40的范围内约束它。

结果,角度值应该在(310,360)和(0,20)的范围内。如果计算出的角度值为304,则角度值应约束为310,如果计算出的角度值为30,则角度值应约束为20.

我已经实现了一种方法,但效率不够(大部分工作都是在角度值接近360~0时解决问题)。请快点达到这个目的的方法是什么?

功能:

// All values are in the range [0.0f, 360.0f]
// Output: the angle value after constraint. 

float _KeepAngleValueBetween(float originalAngle, float currentAngle, float MaxPositiveOffset, float MaxNegativeOffset). 

例如:

KeepAngleValueBetween(350.0f, 302.0f, 30.0f, 40.0f)

结果:310.0f

KeepAngleValueBetween(350.0f, 40.0f, 30.0f, 40.0f)

结果:20.0f

KeepAngleValueBetween(140.0f, 190.0f, 45.0f, 40.0f)

结果:1​​85.0f

1 个答案:

答案 0 :(得分:0)

我无法想出一个不使用if的解决方案。无论如何,我通过在检查currentAngle是否在所需范围内之前翻译值来处理0/360左右的问题。

伪代码(好吧,它是C.它也是有效的Java。和C ++。):

float _KeepAngleValueBetween(float originalAngle, float currentAngle, float MaxPositiveOffset, float MaxNegativeOffset) {

    // Translate so that the undesirable range starts at 0.
    float translateBy = originalAngle + MaxPositiveOffset;
    float result = currentAngle - translateBy + 720f;
    result -= ((int)result/360) * 360;

    float undesiredRange = 360f - MaxNegativeOffset - MaxPositiveOffset;
    if (result >= undesiredRange) {
        // No adjustment needed
        return currentAngle;
    }

    // Perform adjustment
    if (result * 2 < undesiredRange) {
        // Return the upper limit because it is closer.
        result = currentAngle + MaxPositiveOffset;
    } else {
        // Return the lower limit
        result = currentAngle - MaxNegativeOffset + 360f;
    }

    // Translate to the range 0-360.
    result -= ((int)result)/360 * 360; 

    return result;
}