skip to Main Content

I’m working on a program in which i want to store the distance the user walked since pressing a button. I retrieve the distance via geolocator package and display it on screen which works just fine.

I know there are some distanceBetween-Function for locations, but as far as i noticed, they are just calculating the distance between 2 points and not the actual distance the user walked (For example, if the user starts at one point X, walks over to Point Y and back to X would end in comparing start-and endpoint (X to X), which results in distance: 0, but i want the distance X -> Y -> X.

I added following function that calculated the distance based on longitude/latitude.

double distance(Position start, Position current){
  return double.parse((acos(sin(start.latitude)*sin(current.latitude)+cos(start.latitude)*cos(current.latitude)*cos(current.longitude-start.longitude))*6371).toStringAsFixed(2));
}

I call it every frame and store the distance between the current and last gps position.
Works slowly but fine, except one Problem:
Somewhen, the double suddenly turns into "NaN", and i can’t figure out why.
It’s completely random when this occurs – At the beginning, it was always around 0.6, but it also occurred around 4.5 and 0.2, so i think the problem may be somewhere else.

Can anybody help?

Or does anybody knows a built-in-function that can solve the same problem?

I tried parsing the double to only have 2 decimal spaces (Didn’t round it before) because i thought the number might just got too many decimal spaces to be displayed, but error still occured.

I have a second task that is happening at the same time each time stamp, so i thought it was hindering retrieving the GPS, so i tried disabling it, but it didn’t change anything.

2

Answers


  1. Chosen as BEST ANSWER

    I really didn't think about the arccosines domain... So i updated my code with your proposition to:

    double distance(Position start, Position current) {
        double x = sin(start.latitude) * sin(current.latitude) + cos(start.latitude) * cos(current.latitude) * cos(current.longitude - start.longitude);
        if (x > 1 || x < -1) {
          if (kDebugMode) {
            print("error");
          }
          return 0;
        }
        return double.parse((acos(x) * 6371).toStringAsFixed(2));
      }
    

    It works fine, thank you for your help!


  2. It’s possible that you are getting numerical stability issues with the spherical law of cosines since you’re calculating the distance on every frame? It is known that the formula has conditioning issues for very small distances (less than one meter).
    Note that the domain for
    arccosine(x) is given by -1 <= x <= 1. If in your case you were to supply a value greater than 1 (or smaller than -1) you would get a NaN result.
    If you are still debugging this you can add a simple print statement:

    double distance(Position start, Position current){
      double x = sin(start.latitude)*sin(current.latitude)+cos(start.latitude)*cos(current.latitude)*cos(current.longitude-start.longitude);
      if (x > 1 || x < -1) {
        print("error");
      }
      return ((acos(sin(start.latitude)*sin(current.latitude)+cos(start.latitude)*cos(current.latitude)*cos(current.longitude-start.longitude))*6371));
    }
    

    If this is indeed the case, then you have a few options, use the Haversine formula because it is better conditioned for small distances, or simply set x to 1 if it’s above 1. This anyway just means that the distance is zero.


    For more information (and the Haversine formula) see also: Great circle distance

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search