Arc Length by Simpson’s Rule
C++. I applied Simpson’s rule to the integral in the Arc length formula to get an approximate length of a quadratic equation curve. To do that, I applied Simpson rule by sweeping small increments on x axis instead of using full Integral calculations. At the beginning, I chose 100 sub-intervals within [-1,1] to calculate the approximate lengths.
Here, the example functions are: y = x^2 + 1, y = 3x^2 + 2x – 5, and y = -2x^2 + x -3, with the error percentages respectively %2.03, %3.07, and %1.64. If we increase n to 1000, the error percentages are going to be really small like %0.34, %0.42, and %0.20.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
#include <iostream> #include <cmath> template<typename IntegralFunction> float GetApproximateCurveLength (int const n, float const a, float const b, IntegralFunction function) { // Applying Simpson rule to get approximate curve length // where a is the lowerbound and b is the upper bound of the integral float const deltaX = std::abs(b-a) / n; float totalValue = function(a); // First value in the chain for(int i = 1; i < n-1; ++i) { totalValue += 2.0f * (1 + i % 2) * function(a + deltaX * i); } totalValue += function(b); // Last value in the chain return (deltaX / 3.0f) * totalValue; } int main() { // Dividing the interval [a, b] into an even number n of subintervals // with each of width deltaX where n > 0 int n = 100; float const a = -1.0f; // lower bound float const b = 1.0f; // upper bound // Applying Simpson Rule to get approximate curve length with n subintervals // The function inside the integral of Arc Length Formula is (sqrt(1 + (dy/dx)^2)) // The first quadratic to test: y = x^2 + 1 // its function inside the definite integral: f(x) = sqrt(4x^2 + 1) auto IntegralFunctionA = [](float x){ return std::sqrt(4.0f*x*x + 1.0f); }; std::cout << GetApproximateCurveLength(n, a, b, IntegralFunctionA) << std::endl; // The second quadratic to test: y = 3x^2 + 2x - 5 // its function inside the definite integral: f(x) = sqrt(36x^2 +24x + 5) auto IntegralFunctionB = [](float x){ return std::sqrt(36.0f*x*x + 24*x + 5); }; std::cout << GetApproximateCurveLength(n, a, b, IntegralFunctionB) << std::endl; // The third quadratic to test: y = -2x^2 + x - 3 // its function inside the definite integral: f(x) = sqrt(16x^2 -8x + 2) auto IntegralFunctionC = [](float x){ return std::sqrt(16.0f*x*x - 8*x + 2); }; std::cout << GetApproximateCurveLength(n, a, b, IntegralFunctionC) << std::endl; return 0; } |