iBeacon 三边测量 - 矢量数学
iBeacon Trilateration - Vector Math
我在使用 iBeacon 进行三边测量时遇到了一些麻烦。我在 this 线程中找到了一个使用矢量数学的公式,并在我的项目中实现了它。然而,它似乎给了我奇数。
它似乎大部分时间都有效,但我注意到有时当使用截然不同的距离时它会给我极其相似的答案,这对我来说似乎很奇怪。
CGPoint pointA = [[curBlufiPoints objectAtIndex:0] CGPointValue];
CGPoint pointB = [[curBlufiPoints objectAtIndex:1] CGPointValue];
CGPoint pointC = [[curBlufiPoints objectAtIndex:2] CGPointValue];
/*Point A = (40, 612)
Point B = (379, 788)
Point C = (0, 352)*/
float distanceA = [[distances objectAtIndex:0] floatValue];
float distanceB = [[distances objectAtIndex:1] floatValue];
float distanceC = [[distances objectAtIndex:2] floatValue];
/*distanceA = 13.535637
distanceB = 46.931522
distanceC = 51.585461
----OR----
distanceA = 349.9057;
distanceB = 352.84134;
distanceC = 353.37515;*/
CGPoint P2MinusP1 = CGPointMake(pointB.x - pointA.x, pointB.y - pointA.y);
CGPoint P3MinusP1 = CGPointMake(pointC.x - pointA.x, pointC.y - pointA.y);
CGFloat magP2MinusP1 = sqrt(pow((P2MinusP1.x), 2) + pow((P2MinusP1.y), 2));
CGPoint eX = CGPointMake(P2MinusP1.x / magP2MinusP1, P2MinusP1.y / magP2MinusP1);
CGFloat i = eX.x * P3MinusP1.x + eX.y * P3MinusP1.y;
CGPoint eXTimesI = CGPointMake(eX.x * i, eX.y * i);
CGPoint P3MinusP1MinusITimesEX = CGPointMake(P3MinusP1.x - eXTimesI.x, P3MinusP1.y - eXTimesI.y);
CGFloat magP3MinusP1MinusITimesEX = sqrt(pow(P3MinusP1MinusITimesEX.x, 2) + pow(P3MinusP1MinusITimesEX.y, 2));
CGPoint eY = CGPointMake(P3MinusP1MinusITimesEX.x / magP3MinusP1MinusITimesEX, P3MinusP1MinusITimesEX.y / magP3MinusP1MinusITimesEX);
CGFloat j = eY.x * P3MinusP1.x + eY.y * P3MinusP1.y;
CGFloat x = (pow(distanceA, 2) - pow(distanceB, 2) + pow(magP2MinusP1, 2)) / (2 * magP2MinusP1);
CGFloat y = (pow(distanceA, 2) - pow(distanceC, 2) + pow(i, 2) + pow(j, 2)) / (2 * j) - (i * x) / j;
CGPoint finalPoint = CGPointMake(pointA.x + x * eX.x + y * eY.x, pointA.y + x * eX.y + y * eY.y);
NSLog(@"%f %f %f %f", finalPoint.x, finalPoint.y);
//finalPoint.x = ~343
//finalPoint.y = ~437
从我在上面的代码中评论的值可以看出,当我使用相同的点但不同的距离时,我最终得到相同的结果。对我来说,他们怎么能有大致相同的答案是没有意义的。如果点 (343, 437)(我对两组输入得到的答案)与点 (40, 612) 相距 13.5 个单位,那么同一个点怎么也相距 349.9 个单位?
我不确定我的数学哪里出了问题,但我认为有关计算 x 和 y 的部分是问题所在。我发现行 "pow(distanceA, 2) - pow(distanceB, 2)" 和 "pow(distanceA, 2) - pow(distanceC, 2)" 给我两组数字大致相同的答案,这就是为什么无论我使用哪一组数字,x 和 y 最终都是相同的。
我不认为应该是这种情况,任何帮助将不胜感激,谢谢!
我用示例尝试了您的代码(和糟糕的代码测试)。
测试代码为here。
为了调试,我使用 "3D" new feature of XCode 6 来查看超出屏幕边界的点和圆,因为我不想进行平移(重新定位平面等)
主要问题(您的第一个样本测试 (@[@(13.535637), @(46.931522), @(51.585461)];
) 是圆圈不重叠。没有交集。所以您无法猜测位置。
如果您以圆心 pointA 和半径 distanceA 绘制一个圆,并为点 B 和 C 绘制圆,则需要找到要进行地理定位的交点,相关问题的 wiki-related 文章中清楚地说明了这一点。
我添加了一个 "check" 方法来查看它们是否正确重叠,使用 "allowed mistake",因为我们正在用 float 做一些数学运算,可能会有一些舍入问题。
检查方法包括重新计算 finalPoint(找到的坐标)和每个点之间的距离。现在的问题是它们是否与原来的不同(很多?)。
我在使用 iBeacon 进行三边测量时遇到了一些麻烦。我在 this 线程中找到了一个使用矢量数学的公式,并在我的项目中实现了它。然而,它似乎给了我奇数。
它似乎大部分时间都有效,但我注意到有时当使用截然不同的距离时它会给我极其相似的答案,这对我来说似乎很奇怪。
CGPoint pointA = [[curBlufiPoints objectAtIndex:0] CGPointValue];
CGPoint pointB = [[curBlufiPoints objectAtIndex:1] CGPointValue];
CGPoint pointC = [[curBlufiPoints objectAtIndex:2] CGPointValue];
/*Point A = (40, 612)
Point B = (379, 788)
Point C = (0, 352)*/
float distanceA = [[distances objectAtIndex:0] floatValue];
float distanceB = [[distances objectAtIndex:1] floatValue];
float distanceC = [[distances objectAtIndex:2] floatValue];
/*distanceA = 13.535637
distanceB = 46.931522
distanceC = 51.585461
----OR----
distanceA = 349.9057;
distanceB = 352.84134;
distanceC = 353.37515;*/
CGPoint P2MinusP1 = CGPointMake(pointB.x - pointA.x, pointB.y - pointA.y);
CGPoint P3MinusP1 = CGPointMake(pointC.x - pointA.x, pointC.y - pointA.y);
CGFloat magP2MinusP1 = sqrt(pow((P2MinusP1.x), 2) + pow((P2MinusP1.y), 2));
CGPoint eX = CGPointMake(P2MinusP1.x / magP2MinusP1, P2MinusP1.y / magP2MinusP1);
CGFloat i = eX.x * P3MinusP1.x + eX.y * P3MinusP1.y;
CGPoint eXTimesI = CGPointMake(eX.x * i, eX.y * i);
CGPoint P3MinusP1MinusITimesEX = CGPointMake(P3MinusP1.x - eXTimesI.x, P3MinusP1.y - eXTimesI.y);
CGFloat magP3MinusP1MinusITimesEX = sqrt(pow(P3MinusP1MinusITimesEX.x, 2) + pow(P3MinusP1MinusITimesEX.y, 2));
CGPoint eY = CGPointMake(P3MinusP1MinusITimesEX.x / magP3MinusP1MinusITimesEX, P3MinusP1MinusITimesEX.y / magP3MinusP1MinusITimesEX);
CGFloat j = eY.x * P3MinusP1.x + eY.y * P3MinusP1.y;
CGFloat x = (pow(distanceA, 2) - pow(distanceB, 2) + pow(magP2MinusP1, 2)) / (2 * magP2MinusP1);
CGFloat y = (pow(distanceA, 2) - pow(distanceC, 2) + pow(i, 2) + pow(j, 2)) / (2 * j) - (i * x) / j;
CGPoint finalPoint = CGPointMake(pointA.x + x * eX.x + y * eY.x, pointA.y + x * eX.y + y * eY.y);
NSLog(@"%f %f %f %f", finalPoint.x, finalPoint.y);
//finalPoint.x = ~343
//finalPoint.y = ~437
从我在上面的代码中评论的值可以看出,当我使用相同的点但不同的距离时,我最终得到相同的结果。对我来说,他们怎么能有大致相同的答案是没有意义的。如果点 (343, 437)(我对两组输入得到的答案)与点 (40, 612) 相距 13.5 个单位,那么同一个点怎么也相距 349.9 个单位?
我不确定我的数学哪里出了问题,但我认为有关计算 x 和 y 的部分是问题所在。我发现行 "pow(distanceA, 2) - pow(distanceB, 2)" 和 "pow(distanceA, 2) - pow(distanceC, 2)" 给我两组数字大致相同的答案,这就是为什么无论我使用哪一组数字,x 和 y 最终都是相同的。
我不认为应该是这种情况,任何帮助将不胜感激,谢谢!
我用示例尝试了您的代码(和糟糕的代码测试)。 测试代码为here。 为了调试,我使用 "3D" new feature of XCode 6 来查看超出屏幕边界的点和圆,因为我不想进行平移(重新定位平面等)
主要问题(您的第一个样本测试 (@[@(13.535637), @(46.931522), @(51.585461)];
) 是圆圈不重叠。没有交集。所以您无法猜测位置。
如果您以圆心 pointA 和半径 distanceA 绘制一个圆,并为点 B 和 C 绘制圆,则需要找到要进行地理定位的交点,相关问题的 wiki-related 文章中清楚地说明了这一点。
我添加了一个 "check" 方法来查看它们是否正确重叠,使用 "allowed mistake",因为我们正在用 float 做一些数学运算,可能会有一些舍入问题。
检查方法包括重新计算 finalPoint(找到的坐标)和每个点之间的距离。现在的问题是它们是否与原来的不同(很多?)。