Skip to main content
edited for clarity
Source Link

I tried the code above (@Lyra's implementation of @whuber'sAccepted answer) in google-maps, and it gavederivatives didn't work for me. Results were very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist hereCorrect implementation in javascript:

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians (-180 - 180 deg)*/
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

CodeFull gist here

In the accepted answer - I found that points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in the north of Sweden). If I removed the x coord adjustment from @whuber's answer the ellipse is distorted the other way, 8 times higher than its width.

The code in my answer was based on algorithms from here

HereBelow you can see a couple oftwo jsfiddles that show the problem with the stretching ellipse

Correct algorithm

Distorted algorithm

I tried the code above (@Lyra's implementation of @whuber's answer) in google-maps, and it gave very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist here

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians */
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

Code was based on algorithms from here

Here you can see a couple of jsfiddles that show the problem with the stretching ellipse

Correct algorithm

Distorted algorithm

Accepted answer and derivatives didn't work for me. Results were very inaccurate.

Correct implementation in javascript:

function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians (-180 - 180 deg)*/
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

Full gist here

In the accepted answer - I found that points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in the north of Sweden). If I removed the x coord adjustment from @whuber's answer the ellipse is distorted the other way, 8 times higher than its width.

The code in my answer was based on algorithms from here

Below you can see two jsfiddles that show the problem with the stretching ellipse

Correct algorithm

Distorted algorithm

added jsfiddle links and indented code better
Source Link

I tried the code above (@Lyra's implementation of @whuber's answer) in google-maps, and it gave very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist here

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians */
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

The above functions areCode was based on algorithms from here

Here you can see a couple of jsfiddles that show the problem with the stretching ellipse

Correct algorithm

Distorted algorithm

I tried the code above (@Lyra's implementation of @whuber's answer) in google-maps, and it gave very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist here

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
  const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
  const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians */
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

The above functions are based on algorithms from here

I tried the code above (@Lyra's implementation of @whuber's answer) in google-maps, and it gave very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist here

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
    const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
    const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians */
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

Code was based on algorithms from here

Here you can see a couple of jsfiddles that show the problem with the stretching ellipse

Correct algorithm

Distorted algorithm

Source Link

I tried the code above (@Lyra's implementation of @whuber's answer) in google-maps, and it gave very inaccurate results. Specifically the points are distributed in an ellipse with its width 1.5 times its height (in Panama) and 8 times its height (in Sweden). If I remove the x coord adjustment the ellipse is distorted the other way, 8 times higher than its width.

The functions below seem to work correctly.

There is a full gist here

/* 
coords is an object: {latitude: number, longitude: number}
toRadians() and toDegrees() convert both values of the above object
*/
function pointAtDistance(inputCoords, distance) {
    const result = {}
    const coords = toRadians(inputCoords)
    const sinLat =  Math.sin(coords.latitude)
    const cosLat =  Math.cos(coords.latitude)

    /* go a fixed distance in a random direction*/
    const bearing = Math.random() * TWO_PI
    const theta = distance/EARTH_RADIUS
  const sinBearing = Math.sin(bearing)
    const cosBearing =  Math.cos(bearing)
  const sinTheta = Math.sin(theta)
    const cosTheta =    Math.cos(theta)
    
    result.latitude = Math.asin(sinLat*cosTheta+cosLat*sinTheta*cosBearing);
    result.longitude = coords.longitude + 
        Math.atan2( sinBearing*sinTheta*cosLat, cosTheta-sinLat*Math.sin(result.latitude )
    );
    /* normalize -PI -> +PI radians */
    result.longitude = ((result.longitude+THREE_PI)%TWO_PI)-Math.PI

    return toDegrees(result)
}

function pointInCircle(coord, distance) {
    const rnd =  Math.random()
    /*use square root of random number to avoid high density at the center*/
    const randomDist = Math.sqrt(rnd) * distance
    return pointAtDistance(coord, randomDist)
}

The above functions are based on algorithms from here