Inconsistency with Math.Round()

馋奶兔 提交于 2019-12-01 20:47:38

For the angle in degrees, if x is between -180 and 180, then 180 - x is between 0 and 360. What you want is equivalent to asking that 180 - x is between 0 (inclusive), and 360 (exclusive). So, as soon as 180 - x reaches 360, we want to add 360 to the angle. This gives us:

return angle + 360d * Math.Floor((180d - angle) / 360d);

Same thing for the angle in radians:

return angle + twopi * Math.Floor((Math.PI - angle) / twopi);

It does not address the rounding issue, but here is how I would to what you want to do :

private static double ConvertAngle(double angle)
{
    bool isNegative = angle < 0;
    if (isNegative)
        angle *= -1;

    angle = angle % 360;
    if (isNegative)
        angle = -1 * angle + 360;

    if (angle > 180)
        angle = (angle - 360);

    return angle;
}

Note: This way supposes you want "behind" to be 180 degrees, not -180 degrees.

Isn't this a case for a modulo operation?

private double Wrap180(double value)
{
    // exact rounding of corner values
    if (value == 180) return 180.0;
    if (value == -180) return 180.0;

    // "shift" by 180 and use module, then shift back.
    double wrapped = ((Math.Abs(value) + 180.0) % 360.0) - 180.0;

    // handle negative values correctly
    if (value < 0) return -wrapped;
    return wrapped;
}

It passes this tests

    Assert.AreEqual(170.0, wrap(-190.0));
    Assert.AreEqual(180.0, wrap(-180.0));
    Assert.AreEqual(-170.0, wrap(-170.0));
    Assert.AreEqual(0.0, wrap(0.0));
    Assert.AreEqual(10.0, wrap(10.0));
    Assert.AreEqual(170.0, wrap(170.0));
    Assert.AreEqual(180.0, wrap(180.0));
    Assert.AreEqual(-170.0, wrap(190.0));
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!