Working on a tool to make runway recommendations for flight simulation enthusiasts based off of the real world winds at a given airport. The ultimate goal is to compare, and return a list of available runways in a list, with the smallest wind variance displaying at the top of the list.
I would say that I probably have 95% of what I need, but where it gets slippery is for wind headings that approach 0 degrees (360 on a compass rose).
If runway heading is 029 and wind heading is 360, it is only a difference of 29 degrees, but the formula that I have written displays a difference of 331 degrees.
I have tried experimenting with abs() as part of the comparison but have gotten nowhere. I will link my current results here: https://extendsclass.com/php-bin/7eba5c8
Attempted switching comparisons for wind heading and runway heading (subtracting one from the other, and then the other way around) with the same result.
I am sure that the key lies in some little three line nonsense that I just cannot get the knack of (disadvantage of being a self-taught cowboy coder, I guess).
I saw a post about how to do it in C# from about 11 years ago but I never messed around with that particular deep, dark corner of the programming world.
The code is included below:
<?php
echo "<pre>\n";
//Dummy Runways. Will be replaced by data from AVWX
$rwy_hdgs = array(
"04R" => "029",
"04L" => "029",
"22R" => "209",
"22L" => "209",
"03R" => "029",
"03L" => "029",
"21L" => "216",
"21R" => "216",
"09L" => "089",
"09R" => "089",
"27R" => "269",
"27L" => "269"
);
//Dummy Wind Heading. Will be replaced by data from AVWX
$wind_dir = "360";
$runways = array();
$i = 1;
foreach($rwy_hdgs as $key => $value)
{
$diff = $value - $wind_dir;
$runways[$i]["rwy"] = $key;
$runways[$i]["hdg"] = $value;
$runways[$i]["diff"] = abs($diff);
$i ;
}
//Select "diff" value
$diff = array_column($runways, "diff");
//Sort $runways by difference betweeen wind and runways, with smallest value first
array_multisort($diff, SORT_ASC, $runways);
foreach ($runways as $runway){
echo "Wind Heading: " . $wind_dir . "\n";
echo "Runway: " . $runway["rwy"] . "\n";
echo "Heading: " . $runway["hdg"] . "\n";
echo "Variance: " . $runway["diff"] . "°\n\n";
}
echo "</pre>\n";
?>
CodePudding user response:
When you subtract two angles in a circle, you can either go the "short way" or the "long way" - it's a circle... So you have to calculate both ways and then find out, which one is shorter - and the direction too, because you have a fixed start angle and a fixed target angle:
function angleDiff($angleStart, $angleTarget) {
$delta = $angleTarget - $angleStart;
$direction = ($delta > 0) ? -1 : 1;
$absDelta1 = abs($delta);
$absDelta2 = 360 - $absDelta1;
return $direction * ($absDelta1 < $absDelta2 ? $absDelta1 : $absDelta2);
}
This should give you positive numbers for clockwise turning and negative numbers for counter-clockwise turning from start to target angle. Disclaimer: didn't actually test the code, sorry, might have flaws ;)
CodePudding user response:
When I got it right, you want to calculate the difference between two angles always going the short way. So you could do it like this:
$diff = min([abs($a - $b), 360 - abs($a - $b)]);
whith $a
and $b
being the two angles. The result will always be between 0 and 180 degrees.