public static class Program
public static void Main()
private static void TestHCA()
Console.WriteLine("HCA:");
for(int ownshipTrueHeading = 0; ownshipTrueHeading <= 360; ownshipTrueHeading += 45)
for(int othershipTrueHeading = 0; othershipTrueHeading <= 360; othershipTrueHeading += 45)
double hca = HCA(ownshipTrueHeading, othershipTrueHeading);
Console.WriteLine($"{ownshipTrueHeading} => {othershipTrueHeading} = {hca}");
private static void TestAOT()
Console.WriteLine("AOT:");
for(int ownshipTrueHeading = 0; ownshipTrueHeading <= 360; ownshipTrueHeading += 45)
for(int bearingToOthership = 0; bearingToOthership <= 360; bearingToOthership += 45)
double aot = AOT(ownshipTrueHeading, bearingToOthership);
Console.WriteLine($"{ownshipTrueHeading} => {bearingToOthership} => {aot}");
private static double HCA(double ownshipTrueHeading, double othershipTrueHeading)
ownshipTrueHeading = NormalizeHeading(ownshipTrueHeading);
othershipTrueHeading = NormalizeHeading(othershipTrueHeading);
double hca = TurnTowards(ownshipTrueHeading, othershipTrueHeading);
private static double AOT(double ownshipTrueHeading, double bearingToOthership)
ownshipTrueHeading = NormalizeHeading(ownshipTrueHeading);
bearingToOthership = NormalizeHeading(bearingToOthership);
double recipOwnshipHeading = ReciprocalHeading(ownshipTrueHeading);
double aot = TurnTowards(from: recipOwnshipHeading, to: bearingToOthership);
private static double TurnTowards(double from, double to)
int sign = Math.Sign(diff);
double absDiff = Math.Abs(diff);
private static double NormalizeHeading(double heading)
private static double ReciprocalHeading(double heading)
=> (heading + 180) % 360;