0

I have a POI point of interest selected at a certain latitude and longitude and I want to generate a few random point that are at most 50 feet away very accurately. I don't want to go over 50 feet but I also want the random point to be evenly distributed up to the 50 feet.

Here is what I have so far, it looks pretty good but it generates distances that are too far away.

My best guess so far is I think many of my assumptions are based on circles instead of spheres.

x0 = Longitude of POI
y0 = Latitude of POI
u = Uniformly random number between [0,1)
v = Uniformly random number between [0,1)

r = 50*0.3048/111,300
r = maximum 50 foot radius distance new point is away from POI
    0.3048 is to convert feet to meters
    111,300 is to convert meters to degrees for earth

θ (or t) = 2π*v
θ (or t) = Uniformly random rotation around the polar axis

w = r*sqrt(u)
w = Non-uniformly random distance based on polar coordinate system
    so points don’t clump near the center.

Δy = w*sin(θ)
Δy = New random delta change to latitude
     standard w*sin(θ) for converting from polar to Cartesian coordinates

y1 = y0+Δy
y1 = New random latitude of new point

Δx = w*cos(θ)/cos(y1*π/180)
Δx = New random delta change to longitude
     cos(y1*π/180) used to adjust for shrinking east west distances
     as you move further away from the equator

x1 = x0+Δx
x1 = New random longitude of new point

Just to add some more context, I'm doing this inside of SQL Server using a WKID 4326 geography coordinate system and checking my work with STDistance.

Aaron Stainback
  • 3,489
  • 2
  • 31
  • 32
  • you can use my formula ... [equidistant points on sphere](http://stackoverflow.com/a/25031737/2521214). As you are not covering whole globe ignore the `ceil` rounding to keep the points really equidistant – Spektre Mar 26 '16 at 08:38

1 Answers1

0

Just found the solution, it was not anything wrong in my math, it was a bug in converting a float to a VARCHAR in SQL server, I'll include my fixed SQL Server code below. Before where I have:

CONVERT(VARCHAR(50),xxx,3)

I had:

CAST(xxx AS VARCHAR(50))

The default when converting a float to varchar is only 6 significant digits, so I needed to pass a format argument. One thing that is very strange is CAST is not supposed to truncate but in any case it did!! Maybe this is a bug in SQL Server 2016 RC0.

WITH
LoopTable AS (
    SELECT 1 AS i
    UNION ALL
    SELECT i + 1
    FROM LoopTable
    WHERE
    (i + 1) <= 100000
),
InitialPOI AS (
    SELECT geography::STPointFromText('POINT(-81.2545 44.1244)',4326) POI
    FROM LoopTable
)
SELECT NewPoint.Lat NewLat, NewPoint.Long NewLong, Distance
FROM (
    SELECT POI, NewPoint, POI.STDistance(NewPoint)/0.3048 Distance
    FROM (
        SELECT POI, geography::STPointFromText('POINT('+CONVERT(VARCHAR(50),POI.Long+x,3)+' '+CONVERT(VARCHAR(50),POI.Lat+y,3)+')',4326) NewPoint
        FROM (
            SELECT POI, w*COS(t)/COS(POI.Lat*PI()/180) x, w*SIN(t) y
            FROM (
                SELECT POI, 25*0.3048/111300*SQRT(RAND(CHECKSUM(NEWID()))) w, 2*PI()*RAND(CHECKSUM(NEWID())) t
                FROM InitialPOI
            ) i1
        ) i2
    ) i3
) i4
OPTION (MAXRECURSION 0)
Aaron Stainback
  • 3,489
  • 2
  • 31
  • 32
  • This is still not a perfect solution, I get points that are up to 25.05 feet away, it's close enough for me but I would like to get a perfect algorithm. – Aaron Stainback Mar 26 '16 at 16:35