Search code examples
swiftmathswiftuiangle

Angle evaluation in swift, strange behavior when angle close to 360


i am having a trouble when evaluating and comparing some angle.

i have create this function which return a Color base on some condition

i'm passing to the function to parameter which are startingHeading and currentHeading

    func lh1(startHeading:Double, currentHeading : Double)->Color {
        let HDGstart : Angle = Angle(degrees: startHeading)
        let HDHCurrent : Angle = Angle(degrees: currentHeading)
        
        var coloreDaMostrare : Color = .black
        
        if HDHCurrent >= HDGstart - Angle(degrees: 10) && HDHCurrent < HDGstart - Angle(degrees: 5) {
            coloreDaMostrare = .orange
        }
        else if HDHCurrent > HDGstart - Angle(degrees: 5){
            coloreDaMostrare = .black
        }
        else if HDHCurrent < HDGstart - Angle(degrees: 10) {
            coloreDaMostrare = .orange
        }
        
     
        
        return coloreDaMostrare
    }

it work fine when the startingHeading is above 10 deg, but when I'm close to 0/360 it get crazy because the math HDHStart - 10 give a negative angle.

for swift 2 deg - 3 result in -1 but with angle should be 359...

what I'm doing wrong?

is there any way can fix this issue, I have seen few post online the suggest to use modulo-operator .. I have try but swift game warning say can not use in swift ( and to be honest I don't understand how it work)

looking for some help.. thanks a lot


Solution

  • The following function should allow for input angles both smaller and larger than 0...360 to be converted into that range:

    func convertToPositiveAngle(_ angle : Angle) -> Angle {
        var toRet = Angle(degrees: fmod(angle.degrees, 360))
        if toRet.degrees < 0 {
            toRet.degrees += 360.0;
        }
        return toRet
    }
    

    The fmod function is the floating point equivalent of the modulus operator -- it tells you the remainder, basically. So, fmod(370.5, 360) should give you 10.5.

    In your example code, every time you do the subtraction, you should use the above equation. So:

    if HDHCurrent >= convertToPositiveAngle(HDGstart - Angle(degrees: 10)) && HDHCurrent < convertToPositiveAngle(HDGstart - Angle(degrees: 5)) {
    

    etc