百度API提供了在地图上画圆形的类,但画出圆只能是实心圆,也就是不能实现让圆内没有颜色而圆外有颜色的镂空圆。那么我们应该实现镂空圆呢?
首先我发现API还提供一个画多边形的类。而一个镂空圆分解成两个多边形,即横着一刀切在这个镂空圆上,上下两部分各为一个多边形。于是我试着用这种方法画了一个镂空圆,代码详见:百度api中实现 内嵌圆
但实现上述镂空圆时我的思路还是讲经纬度看出笛卡尔坐标系上的x,y,然而经纬度在并不是均匀分布的,这也导致了用上述方法画出的圆一旦离开了赤道就会变成椭圆。
这个问题很棘手,首先我们分析问题,圆的失真是由于经纬度分布不均匀导致的,所以我们不能用笛卡尔坐标系来思考问题,而应该将经纬度转换成球坐标系。维度的范围是大于-90度而小于90度,而球坐标系中的φ的范围是0到180,同理,经度的范围是-180,180,而θ的范围是0,360。很容易找到他们的关系,即φ = 90-维度,
θ = 180-经度;转换公式:(维度,经度) = (φ,θ,R)其中R = 地球半径;
但是得到球坐标系坐标之后分析问题还是十分困难,我们应该将问题转换成我们熟悉的,即将球坐标系转换吃笛卡尔坐标系:
公式如下:
r = √(x²+y²+z²)
θ = arccos[z/√(x²+y²+z²)]
φ = arctan(y/x)
代码实现:
static V3 changeToXyz(LatLng lng){
V3 v = new V3();
if (lng.latitude<0){
v.var1 = 90 + Math.abs(lng.latitude);
}else {
v.var1 = 90 - lng.latitude ;
}
if(lng.longitude<0){
v.var2 = 180 + Math.abs(lng.longitude);
}else {
v.var2 = 180 - lng.longitude;
}
v.var3 = R;
V3 temp = new V3();
temp.var1 = v.var3*Math.sin(Math.PI*v.var1/180)*Math.cos(Math.PI*v.var2/180);
temp.var2 = v.var3*Math.sin(Math.PI*v.var1/180)*Math.sin(Math.PI*v.var2/180);
temp.var3 = v.var3*Math.cos(Math.PI*v.var1/180);
return temp;
}
V3类是我实现vector3的类(即3维向量)