Hello forum,
I'am looking for a way to smooth some existing VertexArray data (x,y).
The data comes from user input via mouse or graphics tablet input.
Maybe somebody can point me into the right direction.
I think i cant implement this myself. So maybe there is some code out there that i can use in C++ ?
Thank you!
I've got this code already but it does not return proper x y coordinates:
void Smooth(sf::VertexArray& vertex)
{
int n = vertex.getVertexCount();
std::vector<int> r(n);
std::vector<float> x;
std::vector<float> y;
for (int i = 0; i < n; i++)
{
x.emplace_back(vertex[i].position.x);
y.emplace_back(vertex[i].position.y);
std::cout << x[i] << " : " << y[i] << std::endl;
}
std::iota(r.begin(), r.end(), 0);
float xm = std::accumulate(x.begin(), x.end(), 0.0) / x.size();
float ym = std::accumulate(y.begin(), y.end(), 0.0) / y.size();
float x2m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a; }) / r.size();
float x3m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a * a; }) / r.size();
float x4m = std::transform_reduce(r.begin(), r.end(), 0.0, std::plus<float>{}, [](float a) {return a * a * a * a; }) / r.size();
float xym = std::transform_reduce(x.begin(), x.end(), y.begin(), 0.0, std::plus<float>{}, std::multiplies<float>{});
xym /= fmin(x.size(), y.size());
float x2ym = std::transform_reduce(x.begin(), x.end(), y.begin(), 0.0, std::plus<float>{}, [](float a, float b) { return a * a * b; });
x2ym /= fmin(x.size(), y.size());
float sxx = x2m - xm * xm;
float sxy = xym - xm * ym;
float sxx2 = x3m - xm * x2m;
float sx2x2 = x4m - x2m * x2m;
float sx2y = x2ym - x2m * ym;
float b = (sxy * sx2x2 - sx2y * sxx2) / (sxx * sx2x2 - sxx2 * sxx2);
float c = (sx2y * sxx - sxy * sxx2) / (sxx * sx2x2 - sxx2 * sxx2);
float a = ym - b * xm - c * x2m;
auto abc = [a, b, c](float xx) {
return a + b * xx + c * xx*xx;
};
std::cout << "y = " << a << " + " << b << "x + " << c << "x^2" << std::endl;
std::cout << " Input Approximation" << std::endl;
std::cout << " x y y1" << std::endl;
//std::cout << sxx << std::endl;
auto xit = x.cbegin();
auto xend = x.cend();
auto yit = y.cbegin();
auto yend = y.cend();
while (xit != xend && yit != yend) {
printf("%2d %3d %5.1f\n", xit, yit, abc(*xit));
xit = std::next(xit);
yit = std::next(yit);
}
}