Coordinate trigonometry - calculate midpoint in arc for flightpath

前端 未结 1 750
旧时难觅i
旧时难觅i 2021-01-07 13:23

I am trying to draw flightpaths on a map using SVGs. I\'m using d3 on top of Leaflet, but the frameworks used shouldn\'t make a difference to my problem - it\'s trig.

相关标签:
1条回答
  • 2021-01-07 13:32

    This is actually easier than you think if you use a custom line generator. Instead of adding the control points to the feature, you just add them during the computation of the path. The code looks like this:

    feature.attr("d", function(d) {
        var s, prev;
        d.geometry.coordinates.forEach(function(c) {
            var proj = map.latLngToLayerPoint(new L.LatLng(c[1], c[0]));
            if(s) {
                var length = Math.sqrt(Math.pow(proj.x - prev.x, 2), Math.pow(proj.y - prev.y, 2)),
                    midx = prev.x + (proj.x - prev.x) / 2,
                    midy = prev.y + (proj.y - prev.y) / 2 - length * 0.2 * (Math.abs(proj.x - prev.x) / length);
                s += "Q" + midx + "," + midy + " " + proj.x + "," + proj.y;
            } else {
                s = "M" + proj.x + "," + proj.y;
            }
            prev = proj;
        });
        return s;
    });
    

    Let's go through it step by step. The main thing is that I'm keeping track of the coordinates of the previous point to be able to compute the control point. First, s will be null and the else branch is taken -- simply move to that point (the start point) without drawing a line. For all subsequent points, the actual computation takes place.

    First, we compute the distance between the two points (previous and current), length. Computing the x coordinate of the control point is straightforward, as no offset is required. The y coordinate is a bit trickier -- the first part is the same, then the offset is added. The size of the offset is 20% of the length of the path here (to make wider arcs for longer paths), adjust as necessary. This needs to be multiplied by the cosine of the angle to the x axis, but fortunately we don't need to compute the angle explicitly -- it is defined by the relation between the distance between the points and the difference in x coordinates (the arc cosine of that angle). So we can just take that relation directly and multiply by it. As you want arcs to point up (i.e. negative y offset), we're taking the absolute value of the x coordinate differences. Without that, some of the control points would be pointing down.

    Complete example here.

    0 讨论(0)
提交回复
热议问题