简体   繁体   English

如何使抛物线适合点集?

[英]How to fit a parabola to set of points?

I have a set of points as seen in the following picture. 我有一些要点,如下图所示。 All points position are known. 所有点的位置都是已知的。 How can I fit a parabola to this set of points and get the new position on parabolic equation (x, y) ? 我如何才能将抛物线拟合到这组点并获得抛物线方程(x, y)的新位置?

在此处输入图片说明

To implement a Quadratic Curve Fitting is not a simple task (check the second link at the end) . 要实现二次曲线合并非易事(请检查最后的第二个链接) As a start you could use simple linear regression , once you've understood the principles (check first link at the end) you can apply it for your case. 首先,您可以使用简单的线性回归 ,一旦您了解了原理(最后检查第一个链接) ,就可以将其应用于您的案例。

The code below is a simple implementation that will fit your data (x, y) to: y = m*x + b : 下面的代码是一个简单的实现,可以将您的数据(x, y)为: y = m*x + b

linear_regression.h : linear_regression.h

#ifndef LINEAR_REGRESSION_H
#define LINEAR_REGRESSION_H
// data structure used as returning type of the function finding m and b
struct Coefficients {
    // constructor
    Coefficients (double mm, double bb)
        : m(mm), b(bb) { }

    // data members 
    double m;
    double b;
};

// This function fits: y = mx + b, to your (x,y) data.
Coefficients linear_regression(const std::vector<double>& x,const std::vector<double>& y){
    // variables needed for the calculations
    double sum_x = 0.0;     double sum_y = 0.0;
    double sum_x2 = 0.0;    double sum_y2 = 0.0;
    double sum_xy = 0.0;

    double m = 0.0;         double b = 0.0;

    if (x.size() != y.size()) std::cerr << "Mismatched number of points!\n";
    double number_of_points = x.size();

    // calculate the sums
    for (size_t i = 0; i < number_of_points; ++i) {
        sum_x  += x[i];
        sum_y  += y[i];          
        sum_x2 += std::sqrt(x[i]); 
        sum_y2 += std::sqrt(y[i]);       
        sum_xy += x[i] * y[i];   
    }
    double denominator = number_of_points * sum_x2 - std::sqrt(sum_x);

    // no solution, return: m = 0, b = 0  
    if (denominator == 0) return Coefficients(m, b);

    // calculate the slope: m and the intercept: b
    m = (number_of_points * sum_xy - sum_x * sum_y) / denominator;
    b = (sum_y * sum_x2 - sum_x * sum_xy) / denominator;

    return Coefficients (m, b);
}
#endif

main.cpp : main.cpp

#include <iostream>
#include <vector>
#include "linear_regression.h"


int main () {
    // vectors holding the set of points
    std::vector<double> x_points;
    std::vector<double> y_points;

    Coefficients coeff = linear_regression (x_points, y_points);

    // where: y = m * x + b
    double m = coeff.m;
    double b = coeff.b;
}

Here, for more information on the method of Linear Regression and Least Squares Regression for Quadratic Curve Fitting . 这里,有关二次曲线拟合 的线性回归最小二乘回归 方法的更多信息。

You could express the curve in polar coordinates (see Wikipedia: “ Polar coordinate system ”). 您可以用极坐标表示曲线(请参见Wikipedia:“ 极坐标系统 ”)。 Just choose an arbitrary point 'inside' the parabola as your origin and transform the (x,y) coordinates to (r,phi) coordinates. 只需在抛物线内部选择任意点作为原点,并将(x,y)坐标转换为(r,phi)坐标。 Now you can express the points in the form r = f(phi) , with r being the distance to the origin and phi being the angle in your polar coordinates. 现在,您可以将点表示为r = f(phi) ,其中r是到原点的距离, phi是极坐标中的角度。 A point that would always do the job as an origin is the average of all points, since it is always located inside the parabola. 一个总能做为原点的点是所有点的平均值,因为它总是位于抛物线内。

In the next step you need to transform the equation of the parabola in your new polar coordinates. 下一步,您需要在新的极坐标中变换抛物线方程。 It needs one extra parameter compared to the simple parabola equation for the rotation. 与简单的抛物线方程相比,它需要一个额外的参数来旋转。 This equation can be used to fit your data, for example using an implementation of the methods described in the Wikipedia article “ Non-linear least squares ”. 该方程式可用于拟合您的数据,例如,使用Wikipedia文章“ 非线性最小二乘法 ”中所述方法的实现。

I don't know if this is the easiest way to solve this problem, but I hope it a least gives you an idea on how you could proceed. 我不知道这是否是解决此问题的最简单方法,但我希望它至少可以使您对如何进行操作有所了解。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM