That subject heading caught me out; I read it like "beta testing"!
I know that it seems as if maths should be able to cope with all input values, but I don't think that's reasonable. In particular if both dx and dy are zero the answer is mathematically indeterminate, so yielding result of zero is arbitrary.
It may be possible to get round the divide-by-zero for only one of dx and dy being zero by calculating the hypotenuse and using ASin or ACos, but I don't think that it is really worthwhile.
Mike (who has cheated and used the algorithm embedded in Basic4PPC open source program GPS4PPC which cites Aviation Formulary V1.45. That has plenty of If's too!)
Thanks for the reply. I'm not too fussed with the division by zero issue (maybe max(dx,0)), more by the "not equal to" issue.
I thought this would be a common problem, and there would be an elegant solution.
regards, Peter
Now I'm confused (as so often...). Isn't the reason for testing for zero (either using "If dx = 0" or "If dx <> 0") just about avoiding division by zero?
And how does "max(dx,0)" help? It would if you introduce an arbitrary minimum value such as "max(dx,0.00001)". But you would also need to know that dx cannot validly be negative and/or include abs(dx) and then re-instate the sign. All a bit heavy!
Mike, partly it is about dividing by zero, but also to test whether dx is +ve or -ve (see back end of the line below). I thought of testing
If dx=0 is false then
if max(dx,0) =0 is then...
but I thought this would be a common problem, and maybe I was ignorant of a more elegant and easy solution.
Thanks, you guys! This forum thingy is great! I think I can sort it- my problem is that true & false don't evaluate to 0 or 1, but the comparitors(?) "<" & ">" are still available- which didn't seem to be the case from help or the manual.
... true & false don't evaluate to 0 or 1, but the comparitors(?) "<" & ">" are still available- which didn't seem to be the case from help or the manual.
Hi again Peter, your original code had "If dy > 0 Then" so I thought you didn't have a problem with the operators. Similarly since I think all your "If"s have "Else"s you don't need "If dx=0 is false then" because you can just swap over the If and Else parts.
I understand that as well as avoiding divide by zero you also need to establish which quadrant your hypotenuse is in to get answers that are not -90 > x < +90.
I hadn't noticed your use of boolean expressions as arithmetic terms, which would work in some languages (and be illegal in others!). Other languages have general expressions in the form (If boolean : value1 ; value2) to provide a neater alternative.
This line: bear1=180-ATan(dy/dx)*rad2degree-90*(dx>0)+90*(dx<0)
will not work in B4PPC !
Logical operators are not accepted in mathematic equations.
I do it that way:
Sub Bearing(dx AsNumber, dy AsNumber) If dx = 0 Then If dy > 0 Then Return 0 Else If dy < 0 Then Return 180 Else Return 999 End If Else If dx > 0 Then Return 90-ATan(dy/dx)*Rad2Degree Else Return 270-ATan(dy/dx)*Rad2Degree End If End If End Sub
Hi Klaus, thanks for your reply and sorry to take so long to respond.
Thinking more about it, and after experimenting and finding that solution does not really work...
(The trouble is that the mean value goes all over the place if small values are mixed up with large ones, so doing Mod 360 cannot cure that.)
I think that the only real answer will be to keep the northing and easting components (with signs) of the successive directions, average them separately, then convert back to a heading. That should remove any idea of one direction (North) being a boundary between large and small bearings...