brain = fried

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:**

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

**Code:**

And I'm then converting these directions to a Whole Circle Bearing, between 0 and 359, with this code:

**Code:**

Which gives directions like this:

**Code:**

And this is where I'm hitting a brick wall. At the moment I'm now doing this:

**Code:**

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.

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:

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;

}

$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:

0

-90 # 90

-180/180

-90 # 90

-180/180

And I'm then converting these directions to a Whole Circle Bearing, between 0 and 359, with this code:

function get_wcb( $az ) {

return ( $az + 360 ) % 360;

}

return ( $az + 360 ) % 360;

}

Which gives directions like this:

359/0

270 # 90

180

270 # 90

180

And this is where I'm hitting a brick wall. At the moment I'm now doing this:

$delta = abs( $wcb1 - $wcb2 )

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

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.

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).

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).

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

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

Worked a treat, thanks again.