坐标三角法 - 计算飞行路径的圆弧中点 [英] Coordinate trigonometry - calculate midpoint in arc for flightpath

查看:230
本文介绍了坐标三角法 - 计算飞行路径的圆弧中点的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用SVG在地图上绘制航迹。我在Leaflet上使用d3,但是使用的框架不应该对我的问题产生影响 - 它是trig。

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.

http://fiddle.jshell.net/zw8TR/26

我想这样做是通过创建一个二次bezier曲线(我打开其他/更容易的方式,如果你知道任何)。我需要计算的是1个控制点,垂直于每条线的中点。这一点总是偏向于比中点更高的y值/纬度,以创建一个看起来像飞行路线的弧。

The way I'm trying to do this is by creating a quadratic bezier curve (I'm open to other/easier ways if you know of any). What I need to calculate is 1 control point, perpendicular to the midpoint of each line. This point should always bias to a higher y value / latitude than the midpoint, to create an arc which looks like a flightpath.

在我上面的演示中,我发现它更容易通过添加一些额外的临时点来精确调试控制点的位置。正如你所看到的,我的一些控制点是朝下的,没有一个看起来是正确的垂直。

In my demo above, I found it's easier to debug exactly where the control point is by adding some extra temporary points. As you can see, some of my control points are facing downwards, and none look to be properly perpendicular.

查看我的上一个问题 - 用图表

我有一个感觉问题归结为这一行: / p>

I have a feeling the problem boils down to this line:

var theta = Math.atan2(t_area_y, t_area_x) * 180 / Math.PI;

我没有正确处理负坐标。我试图在一个令人讨厌的一组如果门来处理这个。

I'm not handling negative coordinates properly. I have tried to hack in a nasty set of if gates to handle this.

我试图很好地评论这个小提琴来解释发生了什么。一旦我知道这一点,应该是在d3中创建自定义插值的简单情况。

I have tried to comment the fiddle nicely to explain what's going on. Once I know the point, it should be a simple case of creating a custom interpolation in d3.

推荐答案

这实际上比你想象如果你使用自定义行生成器更容易。而不是将控制点添加到要素,您只需在路径计算期间添加它们。代码如下:

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

让我们一步一步地完成。主要的是我跟踪上一个点的坐标,以便能够计算控制点。首先, s 将为null,并且采用 else 分支 - 只需移动到该点没有画线。

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.

首先,我们计算两点之间的距离(上一个和当前), length 。计算控制点的 x 坐标是直接的,因为不需要偏移。 y坐标有点棘手 - 第一部分是相同的,然后添加偏移。偏移量的大小为此处路径长度的20%(为较长路径制作较宽的圆弧),必要时进行调整。这需要乘以角度的余弦到 x 轴,但幸运的是我们不需要显式计算角度 - 它是由点之间的距离以及 x 坐标(该角度的反余弦)之间的差异。因此,我们可以直接采用这种关系并乘以它。当你想要弧指向(即负 y offset),我们取的绝对值 x 坐标差。

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.

完成示例此处

这篇关于坐标三角法 - 计算飞行路径的圆弧中点的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆