三点定位法(原理及实现)

三点定位法(原理及实现)

背景

学习笔记
参考 https://blog.csdn.net/jjwwwww/article/details/87714318#_4
由于文中大量数据来自上述博客,因此记为转载

原理

三点定位,顾名思义,需要三个点,这三个点一般为基站,定谁的位置?一般为客户端或者说终端的位置。通过测量终端和基站的距离(这个测量的过程中可能会存在误差,先假设没有误差),将其作为这三个圆的半径,画图,最终求得三圆的交点,交点即为终端位置,达到定位效果。如图。图中O点即为所求。
   在这里插入图片描述

接下来考虑有测量误差的情况。实际测量过程中很容易出现下面的这种情况。这种情况下相交的是一块区域。如图中三个圆的交集为BCE区域。

在这里插入图片描述

这种情况怎么解决?我们先考虑两个圆的情况。这里我们先求C点的坐标。

在这里插入图片描述
两个圆(圆心为基站位置,半径是我们的测量数据即终端到基站的距离)交于A,B两点,连接AB,PQ,AQ,AP, AB和PQ交于点C,圆心的距离PQ在布置完基站之后便已知,圆心和半径已知,联立方程可以求得A,B点的坐标,从而根据欧氏距离求得PA,AQ。根据勾股定理:

在这里插入图片描述

解得
在这里插入图片描述
根据比例关系求得坐标
在这里插入图片描述
三个圆两两进行计算可以得到三个点。之后可以取这三个点的坐标的均值作为终端的坐标。

此外,还有可能会出现以下圆不相交的情况。
在这里插入图片描述
这种情况怎么解决?我们同样先考虑两个圆的情况。如图。此时我们求O点。
在这里插入图片描述
简单的方法是直接根据比例半径计算。
在这里插入图片描述
同样的,最终会得到三个点,取这三个点的坐标的均值作为终端的坐标。

代码

struct Point
{             
	int x;                //x坐标
	int y;                //y坐标
	Point() :x(0), y(0) {};
};

//三点定位法
//dis:半径
//points:圆心
Point threePoints(float *dis, Point *ps) 
{
	Point p;
	if (dis == NULL || ps== NULL)
		return p;

	for (int i = 0; i < 3; ++i)
     {
	    //检查距离是否有问题
		if (dis[i] < 0)
			return Point();

		for (int j = i + 1; j < 3; ++j) 
        {
		    //圆心距离PQ
			float p2p = (float)sqrt((ps[i].x - ps[j].x)*(ps[i].x - ps[j].x) +
				                    (ps[i].y - ps[j].y)*(ps[i].y - ps[j].y));
		    //判断两圆是否相交
			if (dis[i] + dis[j] <= p2p) 
            {
			    //不相交,按比例求
				p.x += ps[i].x + (ps[j].x - ps[i].x)*dis[i] / (dis[i] + dis[j]);
				p.y += ps[i].y + (ps[j].y - ps[i].y)*dis[i] / (dis[i] + dis[j]);
			}
			else
             {
			    //相交则套用公式
                //PC
				float dr = p2p / 2 + (dis[i] * dis[i] - dis[j] * dis[j]) / (2 * p2p); 
                //x = xp + (xq-xp) * PC / PQ
				p.x += ps[i].x + (ps[j].x - ps[i].x)*dr / p2p;
                //y = yp + (yq-yp) * PC / PQ
				p.y += ps[i].y + (ps[j].y - ps[i].y)*dr / p2p;
			}
		}
	}
	
    //三个圆两两求点,最终得到三个点,求其均值
	p.x /= 3;
	p.y /= 3;

	return p;
}

空间多边定位(Multilateration)是一种用于确定物体位置的方,它利用多已知位置的基站(或接收器)来计算目标物体的位置。在三维空间中,至少需要三个基站来确定一个物体的位置。因此,三点定位就是指使用三个基站来确定目标物体的位置。 下面是一个使用C语言实现三点定位示例代码: ```c #include <stdio.h> #include <math.h> // 三点定位函数 void trilateration(double x1, double y1, double z1, double r1, double x2, double y2, double z2, double r2, double x3, double y3, double z3, double r3, double *x, double *y, double *z) { double A1 = 2 * (x2 - x1); double B1 = 2 * (y2 - y1); double C1 = 2 * (z2 - z1); double D1 = pow(r1, 2) - pow(r2, 2) - pow(x1, 2) + pow(x2, 2) - pow(y1, 2) + pow(y2, 2) - pow(z1, 2) + pow(z2, 2); double A2 = 2 * (x3 - x2); double B2 = 2 * (y3 - y2); double C2 = 2 * (z3 - z2); double D2 = pow(r2, 2) - pow(r3, 2) - pow(x2, 2) + pow(x3, 2) - pow(y2, 2) + pow(y3, 2) - pow(z2, 2) + pow(z3, 2); double A3 = 2 * (x1 - x3); double B3 = 2 * (y1 - y3); double C3 = 2 * (z1 - z3); double D3 = pow(r3, 2) - pow(r1, 2) - pow(x3, 2) + pow(x1, 2) - pow(y3, 2) + pow(y1, 2) - pow(z3, 2) + pow(z1, 2); double W = A1 * B2 * C3 + B1 * C2 * A3 + C1 * A2 * B3 - A1 * C2 * B3 - B1 * A2 * C3 - C1 * B2 * A3; double WX = D1 * B2 * C3 + B1 * C2 * D3 + C1 * D2 * B3 - D1 * C2 * B3 - B1 * D2 * C3 - C1 * B2 * D3; double WY = A1 * D2 * C3 + D1 * C2 * A3 + C1 * A2 * D3 - A1 * C2 * D3 - D1 * A2 * C3 - C1 * D2 * A3; double WZ = A1 * B2 * D3 + B1 * D2 * A3 + D1 * A2 * B3 - A1 * D2 * B3 - B1 * A2 * D3 - D1 * B2 * A3; *x = WX / W; *y = WY / W; *z = WZ / W; } int main() { double x1 = 0, y1 = 0, z1 = 0, r1 = 1; double x2 = 3, y2 = 0, z2 = 0, r2 = 2; double x3 = 0, y3 = 4, z3 = 0, r3 = 3; double x, y, z; trilateration(x1, y1, z1, r1, x2, y2, z2, r2, x3, y3, z3, r3, &x, &y, &z); printf("The position of the target is (%.2f, %.2f, %.2f)\n", x, y, z); return 0; } ``` 在这个示例中,我们假设有三个基站分别位于三维空间中的点(0, 0, 0),(3, 0, 0)和(0, 4, 0),它们分别测量到目标物体的距离为1、2和3。使用trilateration函数就可以计算出目标物体的位置,最终输出为(1.50, 2.00, -1.50)。 需要注意的是,这个示例代码只是一个简单的演示,实际应用中可能需要考虑更多的因素,如误差处理等。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值