绘制具有给定半径和两个位置的曲线

时间:2014-07-24 08:09:18

标签: google-maps google-maps-api-3

我有两个位置,我必须根据半径绘制一条曲线。我画了一张图片:

enter image description here

我知道如何绘制圆圈。但是如何只绘制圆圈​​的一部分?

以下是已知参数:

  • 当前位置
  • 下一个位置
  • 曲线/圆的半径

如果有人可以告诉我如何获取当前位置和下一个位置之间的圆圈点,我可以使用折线绘制曲线。但是如何计算位置?

2 个答案:

答案 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);

triangle

正如您现在知道三角形的三个边(弦长,半径(其他两个边)),您可以使用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倍

arc test

答案 1 :(得分:1)

我为我的问题找到了解决方案。

我做的是

  • 获取两点之间的距离(当前位置和下一个位置)
  • 计算sagitta&#39;的值。曲线。
  • 计算当前位置和下一个位置的中点。
  • 计算行当前位置和下一个位置的标题。
  • 从中点开始,在上面的步骤中计算 heading = heading + 90 (如果你想让中心在线的右侧)或在上面计算的 heading = heading步骤 - 90 (如果您希望中心位于线的左侧)和距离=半径 - sagitta,计算偏移点。 enter image description here

可以使用以下公式计算sagitta:

enter image description here

其中,

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))));
    }