在C#中使用信号强度进行网格三角测量算法

6

网格

(角落里的小点是节点,红点是被追踪的人)

坐标:

Node   X    Y   Position
1      0    0   Top left
2    450    0   Top right
3      0  450   Bottom left
4    450  450   Bottom right

Person    X    Y
Red dot  84   68

获取信号强度的方法:

(只需要相对于其他节点的信号强度,它似乎已经实现了。或者我在这里错了吗?)

public int GetSignalStrength(OvalShape node)
{
    int xd = node.Left - this.person.Left;
    int yd = node.Top - this.person.Top;

    var signalStrength = Math.Sqrt((xd * xd) + (yd * yd));

    return Convert.ToInt32(-signalStrength);
}

信号强度:

Node   Signal Strength
1                 -108
2                 -372
3                 -391
4                 -529

获取人员坐标的方法:

(其中s1、s2、s3、s4是以上信号强度)

public int[] GetPositionInGrid(int s1, int s2, int s3, int s4)
{
    var tx1 = this.node1.Left;
    var ty1 = this.node1.Top;

    var tx2 = this.node2.Left;
    var ty2 = this.node2.Top;

    var tx3 = this.node3.Left;
    var ty3 = this.node3.Top;

    var tx4 = this.node4.Left;
    var ty4 = this.node4.Top;

    double w1 = ((double)s1) / ((double)(s1 + s2 + s3 + s4));
    double w2 = ((double)s2) / ((double)(s1 + s2 + s3 + s4));
    double w3 = ((double)s3) / ((double)(s1 + s2 + s3 + s4));
    double w4 = ((double)s4) / ((double)(s1 + s2 + s3 + s4));

    var px = ((tx1 * w1) + (tx2 * w2) + (tx3 * w3) + (tx4 * w4)) / (w1 + w2 + w3 + w4);
    var py = ((ty1 * w1) + (ty2 * w2) + (ty3 * w3) + (ty4 * w4)) / (w1 + w2 + w3 + w4);

    return new int[] { Convert.ToInt32(px), Convert.ToInt32(py) };
}

人员职位:

x: 290
y: 296

你们可以看到我不太擅长数学,而且“人的位置”偏差很大。虽然这并不重要,但如果人在网格中间,则它可以正常工作。

我假设如果每个节点具有相同的信号强度,则该人位于网格中心。

有没有人能帮我解决这个问题?我已经谷歌搜索和苦思冥想了一段时间了。


当人靠近节点时,信号的值会趋近于什么?我猜它会趋近于0? - abelenky
1
你的节点是否总是在四个角落?或者可能会有一个节点,比如在(150, 250)的位置? - crush
@abelenky:是的,这就是我模拟信号强度的方式。目前还没有实际节点。 - Tiax
@crush:我这样做是为了让我更容易地使定位工作正常。我也希望它能够与节点随机放置一起正常工作。 - Tiax
@Kevin:这是个好问题。我得到节点后会告诉你 :P - Tiax
显示剩余7条评论
2个回答

4

解释得很清楚!:) 谢谢! - Tiax

3
您实际上只需要3个节点来完成此操作。
基本概念是,每个信号强度都告诉您与节点的距离。没有其他信息,您可以从每个半径等于信号强度的节点构造一个半圆。当然,人必须位于半圆的某个位置。
因此,使用一个节点,我们构造了一个半圆,结果会出现无数个可能存在的人的位置。
使用两个节点,我们发现两个半圆可能在两个位置相交。事实上,如果人不在屏幕正中心,则两个相反的节点将在窗口边界内的两个不同点相交,但如果人在屏幕中心,则它们只会相交于一个点(中心)。
引入第三个节点后,第三个半圆保证会在它们相交的两个点之一处与前两个半圆相交。
这三个节点相交的位置就是人所在的位置。
正如_the_lotus所说,这是一个三边测量问题。
这是所需函数(您甚至可以从参数列表中剪切s4):
public int[] GetPositionInGrid(int s1, int s2, int s3, int s4)
{
  var px = ((s1 * s1) 
            - (s2 * s2) 
            + (this.node2.Left * this.node2.Left)) 
           / ((double)(2 * this.node2.Left));

  var py = ((s1 * s1) 
            - (s3 * s3) 
            + (this.node3.Left * this.node3.Left) 
            + (this.node3.Top * this.node3.Top)) 
           / (2 * this.node3.Top) 
           - (this.node3.Left / (double)this.node3.Top) 
           * px;

  return new int[] { Convert.ToInt32(px), Convert.ToInt32(py) };
}

我先尝试了三个节点,但为了让它更容易,我加了第四个。我理解概念,只是数学有点难 :P 谢谢你抽出时间来帮助我! - Tiax
@Tiax 我修复了一个小问题。py的计算没有在需要时进行双精度转换。此外,请注意,此解决方案仅适用于node1node2具有相同y值的情况。我正在研究一种不需要这样的解决方案。 - Luke Willis
非常感谢!明天会试着使用它 :) - Tiax
非常好用!如果您解决了node1和node2具有相同y值的“问题”,请告诉我!那将是真正伟大的! - Tiax
@Tiax 很抱歉,我现在没有时间来实现它,但是实现它的算法并不太难。只需要对节点进行预处理和后处理,使它们与规格相匹配,然后将它们移回即可。 - Luke Willis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接