不断缩放3个圆圈,直到它们相交

时间:2019-05-23 11:06:13

标签: python geolocation geometry trilateration

我已经在Python中实现了trilateration定位算法,到目前为止,由于计算出的距离受信号干扰的影响,结果看起来不太理想。

current

应该看起来像这样的时候:

expected

因此,我正在考虑使用恒定因子同时缩放圆,直到它们都在一个点相交(这是最佳的)或直到它们的相互距离之和最小为止。给定2D空间中三个圆的XY坐标,以及它们与参考点的FSPL计算距离(这是一个圆的中心),该函数应返回最佳比例因子,即最小化错误。应该是这样的:

def find_best_scaling_constant(p1, p2, p3, r1, r2, r3):
  # some magic here
  return scalingConstant

find_best_scaling_constant((0.00, 0.00), (3.15, -0.47), (4.90, 7.00), 1.12, 1.77, 0.18)

我不是数学家,所以我不知道这种逻辑是否有意义,但是如果有人有评论或更好的主意,请分享。这将有很大的帮助!

2 个答案:

答案 0 :(得分:1)

让圆的中心为坐标

enter image description here

并让您计算出的相应半径为:

enter image description here

分别。因此,您似乎在寻找具有以下属性的点enter image description here

enter image description here

这也会自动暗示第三个关系

enter image description here

因此,您在帖子中提到的缩放常数是

enter image description here

因此,您具有以下三个方程式的系统:

enter image description here

交叉乘以三个方程,即将第一个方程的两边乘以r1 * r2,第二个方程乘以r2 * r3,第三个方程乘以r3 * r1

enter image description here

然后将每个方程式的两边平方:

enter image description here

根据毕达哥拉斯定理,写下

enter image description here

这就是为什么在明确的公式中,上面的三个平方方程组实际上是二次方程组:

enter image description here

展开每个方程式的所有平方差,例如对于带有下标i和j(其中i = 1,2,3和j = 2,3,1)的方程式:

enter image description here

然后将未知变量的匹配项的项分组在一起,并将所有包含未知变量的项移到每个方程式的左侧。将常数项移到右侧,例如对于具有下标i和j(其中i = 1,2,3和j = 2,3,1)的方程,您将得到:

enter image description here

现在,这是算法开始的地方。设置以下系数

enter image description here

因此,您有了方程组

enter image description here

情况1:假设并非所有三个半径都相等,即至少一对半径不同。然后,至少两个系数rij不等于零。

第一个方程式乘以r23,第二个方程式乘以r12,然后从第一个方程式减去第二个方程式。然后,将第二个方程式乘以r31,第三个方程式乘以r23,然后从第二个方程式中减去第三个方程式。结果是二乘二线性系统

enter image description here

要解决该系统,我们可以使用Cramer's rule for 2 x 2 systems。为此,请先设置

enter image description here

那么您系统的解决方案就是

enter image description here

备注:当三个半径中的两个相等时,说r3 = r2,然后说r12 = r = - r23,而说r31 = 0。该公式仍然可以正常工作。但是,如果愿意,可以取消因数r,以简化方程组。

情况2:假定所有三个半径均相等,即r1 = r2 = r3。然后系统缩小为

enter image description here

因为r1 = r2 = r3 = r将成为所有方程式的公因子,因此可以将其抵消。如果愿意,可以用较短的符号方式将其重写:set

enter image description here

然后系统是

enter image description here

一个方程式是多余的,因为如果从第二个方程式中减去第一个方程式,则会得到第三个方程式。假设您删除了第三个方程式。然后系统缩小为

enter image description here

同样,通过应用Cramer's rule,可以获得解决方案

enter image description here

顺便说一下,圆的中心围绕由三个信号源的位置形成的三角形外接,即外接中心(顺便说一句,也可以通过所述边缘的正交平分线找到系统方程实际上是这些正交平分线的方程,它们在一个公共点(三角形的外接点)处相交。

因此,这是您正在寻找的补丁的解决方案和算法。我建议检查方程式,以确保没有错别字或遗漏任何情况(尽管我认为我涵盖了大多数情况)。

这是对感兴趣的人的@Futurologist方程的python实现。

    def scale_distance(x1, y1, r1, x2, y2, r2, x3, y3, r3):

        r12 = r2**2 - r1**2
        r23 = r3**2 - r2**2
        r31 = r1**2 - r3**2

        a12 = 2*(r1**2 * x2 - r2**2 * x1)
        b12 = 2*(r1**2 * y2 - r2**2 * y1)
        c12 = r1**2*x2**2 + r1**2*y2**2 - r2**2*x1**2 - r2**2*y1**2

        a23 = 2*(r2**2 * x3 - r3**2 * x2)
        b23 = 2*(r2**2 * y3 - r3**2 * y2)
        c23 = r2**2*x3**2 + r2**2*y3**2 - r3**2*x2**2 - r3**2*y2**2

        a31 = 2*(r3**2 * x1 - r1**2 * x3)
        b31 = 2*(r3**2 * y1 - r1**2 * y3)
        c31 = r3**2*x1**2 + r3**2*y1**2 - r1**2*x3**2 - r1**2*y3**2

        det = (a12*r23 - a23*r12)*(b23*r31 - b31*r23) - \
        (a23*r31 - a31*r23) * (b12*r23 - b23*r12)

        # Point of intersection
        x = ((c12*r23 - c23*r12)*(b23*r31 - b31*r23) -
            (c23*r31 - c31*r23)*(b12*r23 - b23*r12)) / det
        y = ((a12*r23 - a23*r12)*(c23*r31 - c31*r23) -
            (a23*r31 - a31*r23)*(c12*r23 - c23*r12)) / det

        k = compute_distance(x, y, x1, y1) / r1 #scaling factor
        return k


    def compute_distance(x1, y1, x2, y2):
        # Computes Pythagorean distance
        return math.sqrt(((x1-x2)**2)+((y1-y2)**2))

答案 1 :(得分:0)

这是对感兴趣的人的@Futurologist方程的python实现。

def scale_distance(x1, y1, r1, x2, y2, r2, x3, y3, r3):

    r12 = r2**2 * r1**2
    r23 = r3**2 * r2**2
    r31 = r1**2 * r3**2

    a12 = 2*(r1**2 * x2 - r2**2 * x1)
    b12 = 2*(r1**2 * y2 - r2**2 * y1)
    c12 = r1**2*x2**2 + r1**2*y2**2 - r2**2*x1**2 - r2**2*y1**2

    a23 = 2*(r2**2 * x3 - r3**2 * x2)
    b23 = 2*(r2**2 * y3 - r3**2 * y2)
    c23 = r2**2*x3**2 + r2**2*y3**2 - r3**2*x2**2 - r3**2*y2**2

    a31 = 2*(r3**2 * x1 - r1**2 * x3)
    b31 = 2*(r3**2 * y1 - r1**2 * y3)
    c31 = r3**2*x1**2 + r3**2*y1**2 - r1**2*x3**2 - r1**2*y3**2

    det = (a12*r23 - a23*r12)*(b23*r31 - b31*r23) - \
    (a23*r31 - a31*r23) * (b12*r23 - b23*r12)

    # Point of intersection
    x = ((c12*r23 - c23*r12)*(b23*r31 - b31*r23) -
        (c23*r31 - c31*r23)*(b12*r23 - b23*r12)) / det
    y = ((a12*r23 - a23*r12)*(c23*r31 - c31*r23) -
        (a23*r31 - a31*r23)*(c12*r23 - c23*r12)) / det

    k = compute_distance((x, y), (x1, y1)) / r1 #scaling factor
    return k


def compute_distance(x1, y1, x2, y2):
    # Computes Pythagorean distance
    return math.sqrt(((x1-x2)**2)+((y1-y2)**2))