在Google Maps API中求解两等圆的两条外公切线及四个交点经纬度
问题需求
在Google Maps API中,获取两个圆心不同但半径相同的圆的两条外公切线,以及四个切点的经纬度。尝试过三角函数、勾股定理等方法自行求解,但遇到困难。
示例基础代码
const citymap = { chicago: { center: { lat: 33.8, lng: 130.6 }, }, newyork: { center: { lat: 35.7, lng: 133 }, } }; function initMap() { // 创建地图 const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: 33.09, lng: 130.712 }, mapTypeId: "terrain", }); // 绘制两个圆 for (const city in citymap) { const cityCircle = new google.maps.Circle({ strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35, map, center: citymap[city].center, radius: 130000, }); } const cirCle1center = new google.maps.LatLng(33.8, 130.6); const cirCle2center = new google.maps.LatLng(35.7, 133); // 绘制两圆心连线 const polyline = new google.maps.Polyline({ path: [ { lat: cirCle1center.lat(), lng: cirCle1center.lng() }, { lat: cirCle2center.lat(), lng: cirCle2center.lng() } ], strokeWeight: 2, strokeColor: '#FFAE00', strokeOpacity: 0.8, strokeStyle: 'dashed', map: map }); } window.initMap = initMap;
解决方案与代码实现
由于两个圆半径相等,外公切线的几何特性为:切线与两圆心的连线垂直,每个切点到对应圆心的连线也与切线垂直。利用Google Maps API的球面几何工具可直接计算,无需手动处理复杂的三角函数转换:
const citymap = { chicago: { center: { lat: 33.8, lng: 130.6 }, }, newyork: { center: { lat: 35.7, lng: 133 }, } }; const RADIUS = 130000; // 圆半径(单位:米) function initMap() { // 创建地图实例 const map = new google.maps.Map(document.getElementById("map"), { zoom: 6, center: { lat: 33.09, lng: 130.712 }, mapTypeId: "terrain", }); // 绘制两个圆 for (const city in citymap) { new google.maps.Circle({ strokeColor: "#FF0000", strokeOpacity: 0.8, strokeWeight: 2, fillColor: "#FF0000", fillOpacity: 0.35, map, center: citymap[city].center, radius: RADIUS, }); } // 定义两个圆心坐标 const center1 = new google.maps.LatLng(33.8, 130.6); const center2 = new google.maps.LatLng(35.7, 133); // 绘制两圆心连线 new google.maps.Polyline({ path: [center1, center2], strokeWeight: 2, strokeColor: '#FFAE00', strokeOpacity: 0.8, strokeStyle: 'dashed', map: map }); // 计算两圆心之间的方向角(从center1指向center2) const heading = google.maps.geometry.spherical.computeHeading(center1, center2); // 计算与圆心连线垂直的两个方向(±90度) const headingPerp1 = (heading + 90) % 360; const headingPerp2 = (heading - 90 + 360) % 360; // 计算四个切点坐标 const tangent1Pt1 = google.maps.geometry.spherical.computeOffset(center1, RADIUS, headingPerp1); const tangent1Pt2 = google.maps.geometry.spherical.computeOffset(center2, RADIUS, headingPerp1); const tangent2Pt1 = google.maps.geometry.spherical.computeOffset(center1, RADIUS, headingPerp2); const tangent2Pt2 = google.maps.geometry.spherical.computeOffset(center2, RADIUS, headingPerp2); // 控制台输出切点经纬度 console.log("第一条外公切线切点:", tangent1Pt1.toJSON(), tangent1Pt2.toJSON()); console.log("第二条外公切线切点:", tangent2Pt1.toJSON(), tangent2Pt2.toJSON()); // 绘制第一条外公切线(绿色) new google.maps.Polyline({ path: [tangent1Pt1, tangent1Pt2], strokeWeight: 3, strokeColor: '#00FF00', strokeOpacity: 0.8, map: map }); // 绘制第二条外公切线(蓝色) new google.maps.Polyline({ path: [tangent2Pt1, tangent2Pt2], strokeWeight: 3, strokeColor: '#0000FF', strokeOpacity: 0.8, map: map }); // 为每个切点添加标记 [tangent1Pt1, tangent1Pt2, tangent2Pt1, tangent2Pt2].forEach(pt => { new google.maps.Marker({ position: pt, map: map, title: `切点:${pt.lat().toFixed(4)}, ${pt.lng().toFixed(4)}` }); }); } window.initMap = initMap;
关键说明
- API依赖:加载Google Maps API时必须引入
geometry库,URL需包含&libraries=geometry,否则computeHeading和computeOffset方法无法使用 - 球面计算优势:使用API内置的球面几何工具,避免手动转换经纬度到平面坐标的误差,尤其是在大区域或高纬度场景下结果更准确
- 几何逻辑:等半径圆的外公切线与圆心连线垂直,沿垂直方向从圆心偏移半径长度即可得到切点,连接对应切点即为外公切线
内容的提问来源于stack exchange,提问作者user16906991
相关产品推荐
相关产品推荐

