极坐标表示中的最小二乘拟合线
Least Squares Fit on Line in polar representation
我在机器人定位系统的基础上工作,说实话,我不确定这是数学问题还是实施问题。我正在尝试使用最小二乘拟合将一条线拟合到一组极坐标。该线以极坐标形式表示。我们的主管给了我两个方程式,一个用于计算角度,一个用于计算到原点的距离。 (见图)
https://i.stack.imgur.com/jUEZ5.png
我尝试用 C++ 实现方程式。
struct Pt {
double d, angle;
};
// Polar coordinates of the points (-2, 1) and (5, 1) respectively.
std::vector<Pt> points = { { 2.2360679774997898, 2.6779450445889870 }, { 5.0990195135927845, 0.19739555984988075 } };
double a, r = 0;
double n = points.size();
double sumOfWeights = n;
double num1 = 0, num2 = 0, den1 = 0, den2 = 0;
for (int i = 0; i < n; i++) {
double iP = points[i].d, iTheta = points[i].angle;
num1 += iP * iP * sin(2 * iTheta);
den1 += iP * iP * cos(2 * iTheta);
for (int j = 0; j < n; j++) {
double jP = points[j].d, jTheta = points[j].angle;
num2 += iP * jP * cos(iTheta) * sin(jTheta);
den2 += iP * jP * cos(iTheta + jTheta);
}
}
a = 0.5 * atan2((num1 - (2.0 / sumOfWeights) * num2), (den1 - (1.0 / sumOfWeights) * den2));
for (int i = 0; i < n; i++) r += points[i].d * cos(points[i].angle - a);
r /= sumOfWeights;
然后我给它点 (-2,1) 和 (5,1) 的极坐标表示,它导致角度为 0,距离为 1.5,这是不正确的,因为直线应该有一个pi/2 的角度和 1 的原点距离,对吗?
我看不出你的代码有任何问题。
在您的示例中,您要查找的行具有等式 y = 1.
根据我的理解,这对应于等于 0 的角度,而不是 pi/2。您表示您的程序提供的角度为 0。
Pi/2是直线最近点到原点的夹角
但是,距离计算存在问题r。下面,我将使用复杂的符号来方便分析:.
对于,您的距离计算对应于:
对于a = 0,这对应于点平均值的实部,在你的例子中确实是1.5。这是你的程序提供的。
将实部替换为虚部即可得到正确的值1,即用sin(.)替换cos(.)。
但是,我不能保证这在所有情况下都有效。我邀请您在互联网上或与您的主管一起检查公式。抱歉暂时不能做得更好。
注意:复杂的符号也可以简化计算。这是一个例子,即使我知道这不是你目前的首要任务:
注意:我无法在第一步中正确显示 Tex 方程。感谢 Bob__ 的评论,我得以改进它。还不够完美...
我在机器人定位系统的基础上工作,说实话,我不确定这是数学问题还是实施问题。我正在尝试使用最小二乘拟合将一条线拟合到一组极坐标。该线以极坐标形式表示。我们的主管给了我两个方程式,一个用于计算角度,一个用于计算到原点的距离。 (见图)
https://i.stack.imgur.com/jUEZ5.png
我尝试用 C++ 实现方程式。
struct Pt {
double d, angle;
};
// Polar coordinates of the points (-2, 1) and (5, 1) respectively.
std::vector<Pt> points = { { 2.2360679774997898, 2.6779450445889870 }, { 5.0990195135927845, 0.19739555984988075 } };
double a, r = 0;
double n = points.size();
double sumOfWeights = n;
double num1 = 0, num2 = 0, den1 = 0, den2 = 0;
for (int i = 0; i < n; i++) {
double iP = points[i].d, iTheta = points[i].angle;
num1 += iP * iP * sin(2 * iTheta);
den1 += iP * iP * cos(2 * iTheta);
for (int j = 0; j < n; j++) {
double jP = points[j].d, jTheta = points[j].angle;
num2 += iP * jP * cos(iTheta) * sin(jTheta);
den2 += iP * jP * cos(iTheta + jTheta);
}
}
a = 0.5 * atan2((num1 - (2.0 / sumOfWeights) * num2), (den1 - (1.0 / sumOfWeights) * den2));
for (int i = 0; i < n; i++) r += points[i].d * cos(points[i].angle - a);
r /= sumOfWeights;
然后我给它点 (-2,1) 和 (5,1) 的极坐标表示,它导致角度为 0,距离为 1.5,这是不正确的,因为直线应该有一个pi/2 的角度和 1 的原点距离,对吗?
我看不出你的代码有任何问题。
在您的示例中,您要查找的行具有等式 y = 1.
根据我的理解,这对应于等于 0 的角度,而不是 pi/2。您表示您的程序提供的角度为 0。
Pi/2是直线最近点到原点的夹角
但是,距离计算存在问题r。下面,我将使用复杂的符号来方便分析:.
对于,您的距离计算对应于:
对于a = 0,这对应于点平均值的实部,在你的例子中确实是1.5。这是你的程序提供的。
将实部替换为虚部即可得到正确的值1,即用sin(.)替换cos(.)。
但是,我不能保证这在所有情况下都有效。我邀请您在互联网上或与您的主管一起检查公式。抱歉暂时不能做得更好。
注意:复杂的符号也可以简化计算。这是一个例子,即使我知道这不是你目前的首要任务:
注意:我无法在第一步中正确显示 Tex 方程。感谢 Bob__ 的评论,我得以改进它。还不够完美...