#pragma once class BezierCurve { static double FactorialLookup[33]; public: // just check if n is appropriate, then return the result static double factorial(int n) { // if (n < 0) { throw new Exception("n is less than 0"); } // if (n > 32) { throw new Exception("n is greater than 32"); } return FactorialLookup[n]; /* returns the value n! as a SUMORealing point number */ } static double Ni(int n, int i) { double ni; double a1 = factorial(n); double a2 = factorial(i); double a3 = factorial(n - i); ni = a1 / (a2 * a3); return ni; } // Calculate Bernstein basis static double Bernstein(int n, int i, double t) { double basis; double ti; /* t^i */ double tni; /* (1 - t)^i */ /* Prevent problems with pow */ if (t == 0.0 && i == 0) ti = 1.0; else ti = pow(t, i); if (n == i && t == 1.0) tni = 1.0; else tni = pow((1 - t), (n - i)); //Bernstein basis basis = Ni(n, i) * ti * tni; return basis; } static glm::vec2 Bezier2D(const std::vector& b, double t) { // if ((1.0 - t) < 5e-6) // t = 1.0; double px = 0.0; double py = 0.0; const int npts = (int)b.size(); for (int i = 0; i < npts; i++) { double basis = Bernstein(npts - 1, i, t); px += basis * b[i].x; py += basis * b[i].y; } return { px, py }; } };