Monday, 21 August 2017

Trigonometric functions and integrals with Js and Canvas

This article will look into displaying trigonometric functions with Javascript and HTML5 Canvas.

A plunk is availble so you can test out different trigonometric functions in Javascript yourself. The following link gives you access to the demo:

Plunk Integral of functions using HTML 5 Canvas and Js
The form input of the demo first asks for an equation to display. Supported here is the format that the Math.Js library supports. You can use for example f(x) = sin(x). I have tested it out with 2D functions supporting one variable x. The drop down lets you choose some prefilled equations for you to test out. The different trigonometric functions supported are the usual ones, also the hyperbolic and arc hyperbolic ones can be tested out, plus some polynomial functions and so on. The Math.Js library will build up a function delegate that can be used in the calculation of the integral and the calculation of the function curve itself.



Method for drawing the equations

The javascript code below is used to draw the equations. We use Math.Js to draw the function, since Math.Js got an excellent parser to build functions that allow different plots of trigonometric functions. But also polynomial equations and so on is supported. Note the math.eval(..) line!

    Graph.prototype.drawEquation = function(polynomialequation, increment, 
     isIntegral, color, thickness, startx, endx){

        var totalArea = 0.0;

        var context = this.context;
        context.save();
        context.save();
        this.transformContext();
        
        //debugger;
        
        var parsedFunc = math.eval(polynomialequation);
        var cury = 0;

        context.beginPath();
     
        cury = parsedFunc(this.minX);
        
        context.moveTo(this.minX, cury);
        
        for(var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) {
   
          cury = parsedFunc(x);
          
          context.lineTo(x, cury);
        }

        context.restore();
        context.lineJoin = 'round';
        context.lineWidth = thickness;
        context.strokeStyle = color;
        context.stroke();
        context.restore();

        if (isIntegral){
            var context = this.context;
            context.save();
            this.transformContext();

            var currentY = 0.0;

            context.lineWidth = 0.1;
            context.strokeStyle = 'red';

            for(var x = startx; x < endx; x += increment) {
              context.beginPath();
              currentY = parsedFunc(x+increment/2.0);
              context.rect(x, 0, increment, currentY);
              totalArea += Math.abs(increment * currentY);
              context.stroke();
            }           
      
        }

        return totalArea.toFixed(2);

      };


Further issues around asymptotic behavior

One thing I have seen is that the calculation of the integral fails to detect asymptotic boundary conditions. For example, the tangens function $$ f(x) = tan(x) $$ has got several asymptotes vertically. These asymptotes occur at the following x-values: $$ \frac{\pi}{2} * (2n+1) $$ for the natural numbers $$ \mathbb{N} $$. Detecting such asymptotes can be very hard, since you have to first decide when a function becomes asymptotic, and you also have to test the function at specific intervals and narrow it down. The Riemann sum as an approximation of the integral will fail for such as asymptotic functions. I use the Midpoint rule in an easy manner here by using the average or middle point of the incrment and look at the function value right there. You could also calculate $$ f(x) $$ at the minimum and maximum part of the increment and average the two function values instead of calculating the function value at the middle point. One other way is to set the increment at a very low value.
You can also test this out yourself! Try setting the increment to a very low value, like 0.00001! You will see that the integral keeps growing as you lower the increment value. This is because small increments for the Riemann sum will more and more find the true integral of the tagens function in this case.
If you are a math student and have good tips here, I would be happy to know more about the strategy around integrals and Riemann sums to deal with asymptotes!

No comments:

Post a Comment