我使用Google地图中的google.maps.geometry.spherical.computeHeading
方法计算JS中Polygon
的路径标题。
我想要做的是计算每两个标题之间的标题。
例如,如果第一条路径的标题是45而第二条路线的标题是135,那么我要寻找的标题应该是90.或者如果第一个标题是350而第二个标题是90,标题I& #39;我要找的是40。
我知道我在这里错过了一些基本的几何学(我在学校里从未擅长数学)。
此外,如果有人知道更优雅的方法来获得多边形的两个路径之间的标题,我愿意接受建议。
我实际上找到了解决问题的方法。它不是很优雅,但它与之前提出的SO问题中的答案非常相似。
/*
* h1 = first heading
* h2 = second heading
*
*/
if (h1 < 0) {
h1 = 360 - Math.abs(h1);
}
h2 = (h2 >= 180) ? h2 - 180 : h2 + 180;
// get average of both headings (i.e. the middle)
bisect = ((h2 + h1) / 2);
// if bisect is > than the h1, we need the inverse
if (bisect > h1) {
bisect = bisect -180;
}
答案 0 :(得分:2)
基本答案:
将所有数字保持在-180到+180的范围内,计算最短距离(将小于180; 180是特殊情况,它有两个答案,两个方向垂直于该线)
假设centerMark位于两条线的公共点,angle1marker和angle2marker从该点开始行。
var hdg1 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle1marker.getPosition());
var hdg2 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle2marker.getPosition());
if (hdg1 > 180) hdg1 -= 360;
if (hdg1 <= -180) hdg1 += 360;
if (hdg2 > 180) hdg2 -= 360;
if (hdg2 <= -180) hdg2 += 306;
var deltaHdg = (hdg1 - hdg2);
if (deltaHdg > 180) deltaHdg -= 360;
if (deltaHdg <= -180) deltaHdg += 360;
var bisectHdg = deltaHdg / 2 + hdg2;
var bisectPosn = google.maps.geometry.spherical.computeOffset(centerMark.getPosition(), 1000, bisectHdg);
代码段:
var map;
var infowindow = new google.maps.InfoWindow();
var bisectLine = null;
var bisectMark = null;
var centerMark = null;
var angle1marker = null;
var angle2marker = null;
function initialize() {
geocoder = new google.maps.Geocoder();
var latlng = new google.maps.LatLng(-34.397, 150.644);
var mapOptions = {
zoom: 15,
center: latlng
}
map = new google.maps.Map(document.getElementById('map-canvas'), mapOptions);
centerMark = new google.maps.Marker({
map: map,
position: map.getCenter()
});
angle1marker = new google.maps.Marker({
map: map,
draggable: true,
position: google.maps.geometry.spherical.computeOffset(map.getCenter(), 1000, 45)
});
google.maps.event.addListener(angle1marker, 'dragend', bisectAngle);
angle2marker = new google.maps.Marker({
map: map,
draggable: true,
position: google.maps.geometry.spherical.computeOffset(map.getCenter(), 1000, 30)
});
google.maps.event.addListener(angle2marker, 'dragend', bisectAngle);
var poly1 = new google.maps.Polyline({
path: [centerMark.getPosition(), angle1marker.getPosition()],
map: map
});
poly1.binder = new MVCArrayBinder(poly1.getPath());
angle1marker.bindTo('position', poly1.binder, '1');
var poly2 = new google.maps.Polyline({
path: [centerMark.getPosition(), angle2marker.getPosition()],
map: map
});
poly2.binder = new MVCArrayBinder(poly2.getPath());
angle2marker.bindTo('position', poly2.binder, '1');
var bounds = new google.maps.LatLngBounds();
bounds.extend(centerMark);
bounds.extend(angle1marker);
bounds.extend(angle2marker);
map.fitBounds(bounds);
}
google.maps.event.addDomListener(window, 'load', initialize);
function bisectAngle() {
var hdg1 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle1marker.getPosition());
var hdg2 = google.maps.geometry.spherical.computeHeading(centerMark.getPosition(), angle2marker.getPosition());
if (hdg1 > 180) hdg1 -= 360;
if (hdg1 <= -180) hdg1 += 360;
if (hdg2 > 180) hdg2 -= 360;
if (hdg2 <= -180) hdg2 += 306;
var deltaHdg = (hdg1 - hdg2);
if (deltaHdg > 180) deltaHdg -= 360;
if (deltaHdg <= -180) deltaHdg += 360;
var bisectHdg = deltaHdg / 2 + hdg2;
document.getElementById('info').innerHTML = "a1=" + hdg1.toFixed(2) + ", a2=" + hdg2.toFixed(2) + ", bA=" + bisectHdg.toFixed(2);
var bisectPosn = google.maps.geometry.spherical.computeOffset(centerMark.getPosition(), 1000, bisectHdg);
if (bisectMark && bisectMark.setMap) {
// bisectMark.setMap(null);
bisectMark.setPosition(bisectPosn);
} else {
bisectMark = new google.maps.Marker({
position: bisectPosn,
map: map
});
}
if (bisectLine && bisectLine.setMap) {
// bisectLine.setMap(null);
bisectLine.setPath([centerMark.getPosition(), bisectPosn]);
} else {
bisectLine = new google.maps.Polyline({
path: [centerMark.getPosition(), bisectPosn],
map: map
});
}
}
/*
* Use bindTo to allow dynamic drag of markers to refresh poly.
*/
function MVCArrayBinder(mvcArray) {
this.array_ = mvcArray;
}
MVCArrayBinder.prototype = new google.maps.MVCObject();
MVCArrayBinder.prototype.get = function(key) {
if (!isNaN(parseInt(key))) {
return this.array_.getAt(parseInt(key));
} else {
this.array_.get(key);
}
}
MVCArrayBinder.prototype.set = function(key, val) {
if (!isNaN(parseInt(key))) {
this.array_.setAt(parseInt(key), val);
} else {
this.array_.set(key, val);
}
}
html,
body,
#map-canvas {
height: 100%;
width: 100%;
margin: 0px;
padding: 0px
}
<script src="https://maps.googleapis.com/maps/api/js?sensor=false&libraries=geometry&ext=.js"></script>
<div id="info"></div>
<div id="map-canvas"></div>