Jump to content
The simFlight Network Forums

FsLatLonPoint.DistanceFromInNauticalMiles(FsLatLonPoint Point) returns NaN in rare conditions


Timothee1

Recommended Posts

Hi

As stated in the title I have some rare conditions where DistanceFromInNauticalMiles() returns NaN instead of a number.
I try to track the flown distance. To accomplish this, I get the current coordinates and one minute later the new coordinates, calculate the distance between both points and sum up the total distance everytime.

I simplified my code a little bit to show you what I have. The method CalcPlayerDistance() is the original method I'm using in my program. The main() method is just used to demonstrate how the logic works.
 

internal class Program
{
  private FsLatitude previousPlayerLatitude;
  private FsLongitude previousPlayerLongitude;

  internal FsLatitude PlayerLatitude { get; private set; }
  internal FsLongitude PlayerLongitude { get; private set; }
  internal double TrackedPlayerDistance{ get; private set; }

  private Offset<long> playerLatitudeOffset = new Offset<long>(0x0560);
  private Offset<long> playerLongitudeOffset = new Offset<long>(0x0568);

  private double CalcPlayerDistance()
  {
      double playerDistance;
      
      PlayerLongitude = new FsLongitude(playerLongitudeOffset.Value);
      PlayerLatitude = new FsLatitude(playerLatitudeOffset.Value);

      // Initialize previous coordinates on start
      if (previousPlayerLatitude.DecimalDegrees == 0 && previousPlayerLongitude.DecimalDegrees == 0 && TrackedPlayerDistance == 0)
      {
          previousPlayerLatitude = PlayerLatitude;
          previousPlayerLongitude = PlayerLongitude;
      }

      FsLatLonPoint currentPosition = new FsLatLonPoint(PlayerLatitude, PlayerLongitude);
      playerDistance = currentPosition.DistanceFromInNauticalMiles(new FsLatLonPoint(previousPlayerLatitude, previousPlayerLongitude));
      previousPlayerLatitude = PlayerLatitude;
      previousPlayerLongitude = PlayerLongitude;

      return playerDistance;
  }
  
  [STAThread]
  public static void Main()
  {
    Program distanceTest = new Program();
    
    while(true)
    {
      distanceTest.TrackedPlayerDistance += distanceTest.CalcPlayerDistance();
      Thread.Sleep(60000);
    }
  }
}

At the end I rarely end up with TrackedPlayerDistance being NaN. Unfortunately I can't reproduce it and I dont know when it happens yet since once TrackedPlayerDistance is NaN it will stay NaN.

Im using the same method to calculate the remaining distance to the destination airport:

DistanceToDestNm = (int)Math.Round(new FsLatLonPoint(PlayerLatitude, PlayerLongitude).DistanceFromInNauticalMiles(arrivalAirport));

This would not directly end up in NaN since im casting to int but instead would end up in something like -2147483648. Unlike the first case it never happened here.

Does anyone have an idea what im doing wrong in the first case and how to prevent it? If there is a better way to accomplish what I'm looking for I'm happy for hints.

 

Regards

Edited by Timothee1
Link to comment
Share on other sites

Hi,

This is the correct way of calculating the distance flown by the player. I can't think of a better way.

I think the NaN is likely being caused by an 'edge case' that isn't being handled correctly by the DistanceFromInNauticalMiles() method. I can't see anything in your code that would cause this.

I will do some testing on that method and see if I can track it down...

Paul

Link to comment
Share on other sites

I've found the problem - I use doubles for the internal calculation and sometimes the precision limitations of floating point types causes extra decimal places. e.g. 1 sometimes end up being 1.0000000001. Not normally an issue but that causes Math.Acos to return NaN as it's over 1.

I've clamped the values from -1 to +1 to account for this so it should be solid now.

Version 3.1.13 has the fix and it now up on NuGet.

Thanks for reporting this and for the example code to reproduce the problem. It was very helpful.

Paul

 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use. Guidelines Privacy Policy We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.