Be Excellent To Each Other
https://www.beexcellenttoeachother.com/forum/

Maths help!
https://www.beexcellenttoeachother.com/forum/viewtopic.php?f=3&t=11544
Page 1 of 1

Author:  GazChap [ Fri Jul 31, 2020 17:23 ]
Post subject:  Maths help!

Perhaps it's just the 31 degree heat, but I cannot fucking work this out for the life of me.

Situation is that I have two sets of two latitude/longitude co-ordinates, each representing a journey from A to B (as the crow flies). What I want to do, is find out if those two journeys are headed in roughly the same direction (with a configurable tolerance, at the moment it should "match" if route 2 is within 45 degrees either side of route 1)

So I've got some PHP code calculating what I believe is called the "forward azimuth" for each:
Code:
function get_forward_azimuth( $lat1, $lng1, $lat2, $lng2 ) {
   $delta_lng = deg2rad( $lng2 - $lng1 );
   $lat1 = deg2rad( $lat1 );
   $lat2 = deg2rad( $lat2 );
   $y = sin( $delta_lng ) * cos( $lat2 );
   $x = cos( $lat1 ) * sin( $lat2 ) - sin( $lat1 ) * cos( $lat2 ) * cos( $delta_lng );
   $az = round( rad2deg( atan2( $y, $x ) ) );
   return $az;
}


This returns a figure between -180 and 180, in these directions:
Code:
      0

-90   #   90

  -180/180


And I'm then converting these directions to a Whole Circle Bearing, between 0 and 359, with this code:
Code:
function get_wcb( $az ) {
   return ( $az + 360 ) % 360;
}


Which gives directions like this:
Code:
    359/0

270   #   90

     180


And this is where I'm hitting a brick wall. At the moment I'm now doing this:
Code:
$delta = abs( $wcb1 - $wcb2 )

if ( $delta <= $tolerance * 2 ) return true;


And this works perfectly (I think) except for anything that crosses that boundary at 359/0, where the maths doesn't stack up.

Feel like I'm missing something super-obvious, but have no idea what.

Author:  Joans [ Fri Jul 31, 2020 19:41 ]
Post subject:  Re: Maths help!

It's hot here too, but let's try this.
If $delta is > 180, then you've effectively gone the wrong way round the circle, so add 360 to to smallest of $wcb1 or $wcb2, then calculate $delta again.

I think that works, so your issue at the moment is, say if $wcb1 = 10 and $wcb2 is 350, $delta = 340, rather than 20, work out the difference between 10 + 360 and 350, and you get your answer.
That should work for everything else, even not crossing the 360/0 boundary, because if you've got $wcb1 = 90 and $wcb2 = 280, then the $delta will be 190, rather than 170 (but I guess that's way out of tolerance, so you wouldn't care).

Author:  GazChap [ Sat Aug 01, 2020 6:47 ]
Post subject:  Re: Maths help!

Fuck, of course - that’ll be the super obvious thing, then; just add to the numbers sufficiently that there effectively is no “crossover”.

I was so fixated on keeping the directional element to it, but at that point there’s really no need as all I’m doing is comparing the two values, makes perfect sense.

Thanks (again) - haven’t tried it yet, but running it through in my head I can’t see any reason it wouldn’t work :)

Author:  GazChap [ Sat Aug 01, 2020 13:15 ]
Post subject:  Re: Maths help!

Worked a treat, thanks again.

Author:  Joans [ Sat Aug 01, 2020 16:30 ]
Post subject:  Re: Maths help!

Happy to help.

Page 1 of 1 All times are UTC [ DST ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/