实际解决问题
高德地图,百度地图求方圆五米内的一个随机经纬度
方案一
随机产生(x,y)
去除不在圆内的点
public LatLng getRandomLatLng(LatLng point) {
Random random = new Random();
double cirx = point.latitude;
double ciry = point.longitude;
double circleR = 0.00025;
double r2 = Math.pow(circleR, 2);
double x = (random.nextInt(500) * 0.000001) - circleR;
double y = (random.nextInt(500) * 0.000001) - circleR;
if (r2 > Math.pow(x, 2) + Math.pow(y, 2)) {
return new LatLng(cirx + x, ciry + y);
}
return getRandomLatLng(point);
}
方案二
用极坐标的方法
其中 0 ⩽ r ⩽ R,0 ⩽ theta < 360 t为0-1均匀分布产生的随机数,r=sqrt(t)∗R
如果单纯用极坐标的话,中间的点会比较密集所以对r添加一个开方因子具体证明
public LatLng getRandomLatLng(LatLng point) {
Random random = new Random();
double cirx = point.latitude;
double ciry = point.longitude;
double circleR = 0.000250;
double r = Math.sqrt(Math.random()) * circleR;
double theta = random.nextInt(3600000) * 0.0001;
double x = r * Math.sin(theta);
double y = r * Math.cos(theta);
return new LatLng(cirx + x, ciry + y);
}
纯极坐标
添加随机因子
方案三
根据该公式先确定一个x,然后解出y的范围,添加一个随机因子就可以了。
该方案的弊端是会使y(或者x看确定的哪个)两端的点变得很密集。不能够平均的分布
public LatLng getRandomLatLng(LatLng point) {
Random random = new Random();
double cirx = point.latitude;
double ciry = point.longitude;
double circleR = 0.000250;
double x = (random.nextInt(500) * 0.000001) - circleR;
double c = (random.nextInt(2000000) * 0.000001) - 1;
double y = c * Math.sqrt(circleR * circleR - x * x);
return new LatLng(cirx + x, ciry + y);
}
什么,你说我的圆不够圆?
原因在这:
地球半径:6371000M
地球周长:2 * 6371000M * π = 40030173
纬度38°地球周长:40030173 * cos38 = 31544206M
任意地球经度周长:40030173M
经度(东西方向)1M实际度:360°/31544206M=1.141255544679108e-5=0.00001141
纬度(南北方向)1M实际度:360°/40030173M=8.993216192195822e-6=0.00000899
经度(东西方向)100M实际度:0.00001141°* 100=0.001141°
纬度(南北方向)100M实际度:0.00000899°* 100=0.000899°
这下就圆了