Reputation: 1136
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)
?
Upvotes: 3
Views: 4502
Reputation: 6467
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
:
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
:
#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.
Upvotes: 1
Reputation: 738
You could express the curve in polar coordinates (see Wikipedia: “Polar coordinate system”). Just choose an arbitrary point ‘inside’ the parabola as your origin and transform the (x,y)
coordinates to (r,phi)
coordinates. 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. 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”.
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.
Upvotes: 0