我有两个位置,我必须根据半径绘制一条曲线。我画了一张图片:
我知道如何绘制圆圈。但是如何只绘制圆圈的一部分?
以下是已知参数:
如果有人可以告诉我如何获取当前位置和下一个位置之间的圆圈点,我可以使用折线绘制曲线。但是如何计算位置?
答案 0 :(得分:1)
您可以使用此Answer绘制弧。
找到弧的中心。
您可以使用Google Geometry库查找2个标记之间的和弦长度,其方位和圆弧中心的位置。
来自文档
computeDistanceBetween(from:LatLng,to:LatLng,radius?:number)返回 两个LatLng之间的距离,以米为单位的数字。半径 默认为地球半径(米)(6378137)。
computeHeading(from:LatLng,to:LatLng)从一个返回标题 LatLng到另一个LatLng。标题以顺时针方向表示 来自北方的范围[-180,180]作为数字。
computeOffset(from:LatLng,distance:number,heading:number, radius?:number)返回移动距离得到的LatLng 来自指定标题中的原点(以度为单位表示 从北方顺时针方向)作为LatLng。
首先找到2个标记之间的距离
var spherical = google.maps.geometry.spherical;
var point1 = markers[0].getPosition();
var point2 = markers[1].getPosition();
var length = google.maps.geometry.spherical.computeDistanceBetween(point1,point2);
然后找到承载
var heading = google.maps.geometry.spherical.computeHeading(point1,point2);
正如您现在知道三角形的三个边(弦长,半径(其他两个边)),您可以使用law of cosines来计算弧心的方位。(注意注释中有两个解决方案)
function solveAngle(a, b, c) { // Returns angle C using law of cosines
var temp = (b * b + c * c - a * a) / (2 * b * c);
if (temp >= -1 && temp <= 1)
return Math.acos(temp);
else
throw "No solution";
}
var baseAngle = solveAngle(radius, radius, c);
var vertexAngle = solveAngle(c,radius,radius);
baseAngle
用于查找中心点的方位。
vertexAngle
个点数。
知道方位和半径,你可以找到圆弧的中心。
var centerPoint = spherical.computeOffset(point1,radius,heading+baseAngle);
注意以米为单位的距离。将方法中的半径更改为3,959英里。
如果半径改变,则中心改变。黄点是蓝点半径的2倍
答案 1 :(得分:1)
我为我的问题找到了解决方案。
我做的是
可以使用以下公式计算sagitta:
其中,
l 是当前位置与下一个位置之间距离的一半
r 是曲线半径
s 是sagitta
我使用的代码是:
function DrawCurvedLine(startLatitude, startLongitude, endLatitude, endLongitude, roc, lineColor) {
var distance;
var latLng1, latLng2;
var sagitta;
var midPoint;
var heading;
var roc;
var center;
var arc = new Array();
curvePoints = [];
// Create current and predicted latlng objects
latLng1 = new google.maps.LatLng(startLatitude, startLongitude);
latLng2 = new google.maps.LatLng(endLatitude, endLongitude);
// Compute the distance between current location and predicted location
distance = google.maps.geometry.spherical.computeDistanceBetween(currentLatLng, predictedLatLng);
sagitta = computeSagitta(roc, (distance / 2));
midPoint = getMidPoint(latLng1, latLng2);
heading = google.maps.geometry.spherical.computeHeading(latLng1, latLng2);
heading = headingClPl + 90;
center = google.maps.geometry.spherical.computeOffset(midPoint, (roc - sagitta), headingClPl);
var Heading1 = google.maps.geometry.spherical.computeHeading(center, latLng1);
var Heading2 = google.maps.geometry.spherical.computeHeading(center, latLng2);
var i = 0;
while ((Heading1 + i) <= Heading2 || (Heading2 + i) <= Heading1) {
if (radiusOfCurve < 0) {
arcPts.push(google.maps.geometry.spherical.computeOffset(centerOfCurve, roc, Heading1 - i));
}
else {
arcPts.push(google.maps.geometry.spherical.computeOffset(centerOfCurve, roc, Heading1 + i));
}
i++;
}
var curvedLine = new google.maps.Polyline({
path: arcPts,
icons: [{
icon: {
path: google.maps.SymbolPath.FORWARD_OPEN_ARROW,
scale: 3,
strokeColor: lineColor,
strokeOpacity: 1,
strokeWeight: 1.3,
fillColor: 'transparent',
fillOpacity: 0
},
offset: '100%'
}],
strokeColor: lineColor,
strokeOpacity: 0.5,
strokeWeight: 2,
map: map
});
function computeSagitta(radius, length){
// radius is radius of circle. length is the half length of chord
return (radius - (Math.sqrt((radius * radius) - (length * length))));
}