## Saturday, 19 August 2017

### Integrals in math with Javascript

This article will describe a demo how to calculate and display definite integrals in a web browser using the HTML 5 <Canvas> element and demonstrate an approximation of integrals using the method of summing up the rectangles between a function curve and the x-axis, that is the equation under consideration to do the calculation of the definite integral on. The integral is defined as the area between the function curve and the x-axis.
Note that we in this demo will consider equations on the form of polynomial curves.
The picture reads integration, it should be integrals! Lets first look some math of how to do the integral of our example, we consider polynomials here, which will be defined as:
$$y = f(x) = ax^3 + bx^2 + cx + d$$ The integral will be the areal between the function f(x) between startx and endx. Consider the following definition of the indefinite integral: $$\int f(x)\ dx$$ The definite area is then between startx s and endx e is then: $$\int_s^e f(x)dx$$ Some math ensues of to check the calculation of the integral (area), consider this following example :
$$a = 0.05, b = 0.05, c = 0.05, d = 1$$. We consider x to be between 1 and 4. Manually calculating the area results in the calculated area of 7.614 (the image shows 7.62, but a check showed it to be 7.614).
Calculation of the integral uses in the hand written calculation the start and end x-values and subtracting the end value of the integral formula with the start value. We consider x here to be between [1..4]. As the screen shot of the demo displays, we approximate this integral to the value 7.60 by calculating the integral as the sum of the midpoint rectangles.

The difference in the specific example between the hand written calculation of 7.62 (exact integral) and approximation of 7.60 is because of the fact that we approximate the integral by summing up the rectangles below the curve. Actually in some cases part of the rectangles are above the curve, there is some discrepancy between the approximate rectangle shape and the true shape of the integral. To get an even more exact value, reducing the increment from 0.5 to 0.25 will get a closer value to the exact one. Reducing the increments will result in smaller rectangles (thinner) following the curve more exact.

Now that we see that our math is sound, we can look at a Plunk with a demo displaying this.
Math integral demo - Plunk
In the sample the graph is displayed with Canvas in HTML 5. The following function in Javascript is used to display the integral and the midpoint rectangles:


Graph.prototype.drawPolynomial = function(polynomialequation, a, b, c, d,
increment, isIntegral, color, thickness, startx, endx){

var totalArea = 0.0;

var context = this.context;
context.save();
context.save();
this.transformContext();

context.beginPath();
context.moveTo(this.minX, polynomialequation(a, b, c, d, this.minX));

for(var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) {
context.lineTo(x, polynomialequation(a, b, c, d, x));
}

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 = polynomialequation(a, b, c, d, (x+increment/2.0));
context.rect(x, 0, increment, currentY);
totalArea += increment * currentY;
context.stroke();
}

}

}



The following code is used to get the values for the coefficients of the polynomial equation and draw the polynomial function and the corresponding approximation rectangles for the integral.



$(document).ready(function(){$("#btnDemo").click(function(){

$("#a").val("0.05");$("#b").val("0.05");
$("#c").val("0.05");$("#d").val("1");
$("#increment").val("0.25");$("#startx").val("1.0");
$("#endx").val("4.0");$("#btnGraph").click();

});

$("#btnGraph").click(function(){ var a,b,c,d,increment,startx,endx = 0; a = parseFloat($("#a").val());
b = parseFloat($("#b").val()); c = parseFloat($("#c").val());
d = parseFloat($("#d").val()); increment = parseFloat($("#increment").val());
startx = parseFloat($("#startx").val()); endx = parseFloat($("#endx").val());

var myGraph = new Graph({
canvasId: 'Graph',
minX: -10,
minY: -10,
maxX: 10,
maxY: 10,
unitsPerTick: 1
});

var totalArea = myGraph.drawPolynomial(function(a,b,c,d,x){
return ((a*x*x*x) + (b * x*x) +  c*x + d * 1.0).toFixed(2);
}, a, b, c, d, increment, true, 'blue', 1.0,  startx, endx);

$("#detailsInfo").append("Total area under graph: " + totalArea); }); });  There is a lot of code to digest here, see through the code in the Plunk the article points to. The key points here is that we pass in a function as a delegate to be our Polynomial equation. We also approximate the integral (area) by summing up the rectangles below it. ### Note that this demo also supports calculating the integral when it dips below the positive y axis! ### Fix of reloading functionality One issue with Canvas and a central one is the fact that the Canvas in HTML 5 is a rasterized grid. It is more like a single layer Photoshop image than a vectorized canvas like Illustrator. With that fact in mind, clearing the Canvas for a new redrawing functionality proved hard. In addition, I also use a transformation here from View-Coordinates to Object-Coordinates. A brute force redrawing is therefore preferred. The following ReloadCanvas method will fix this!  function ReloadCanvas(canvasId){ //debugger; var oldCanvas = document.getElementById(canvasId); console.log("Old canvas: " + oldCanvas); var newCanvas = document.createElement('canvas'); var oldWidth = 500; var oldHeight = 500; if (oldCanvas){ oldWidth = oldCanvas.width; oldHeight = oldCanvas.height; oldCanvas.parentNode.removeChild(oldCanvas); } newCanvas.id = 'Graph'; newCanvas.width = oldHeight; newCanvas.height = oldWidth; document.body.appendChild(newCanvas); }  We detach the old canvas and insert a new one into the DOM (Document Object Model). I use here old api methods, you could also resort to more use of jQuery of course. Note that I try to get the old Canvas width and height and copy this to the new blank Canvas that I insert. You must use parentNode here to to the appendChild and removeChild methods to do the replacement of Canvas. This way, we can paint the Canvas again with a fresh new Canvas and have a simpler demo! I have updated the Plunk with a fixed Fork below: Plunk - Integral math demo app This demo also supports not only a convenient reload method to make the demo easier to test out, but also supports "negative integrals", i.e. sections where the integral dips below the x-axis as shown in the following image: ### Note about accuracy The total area calculated uses some rounding here. I used the .toFixed(2) to stick to a precision of 0.01. You can try out .toFixed(3) to test out a better precision. That will calculate even more precise the calculated area. The increments should of course be small and you will also see that some small values are still imprecise. We calculate the y value to be the midpoint of the polynomial f(x) and the midpoint should follow the curve as good as possible. Actually this integral demo app can support other equations that just polynomials. We could support for example trigonometric functions and so on also. I will look at this in a future demo+article! So there you have it, Canvas and Js can tutor kids and students math concepts in Calculus quite elegant in a web browser. We are seeing that Javascript and HTML 5 are now just as powerful as Java applets in the good old days to describe different concepts and prove that once again Math is fun, especially when computers also come into play! ## Note for students What we have used in this demo is the calculation of definite integrals using the Midpoint Rule and Riemann sum. You can read more about it here. This is standard 1st year Calculus syllabus. Riemann Sums (Wikipedia) ## Monday, 7 August 2017 ### Finding intersection between two lines with HTML5 and Javascript This article will look at detecting intersection of two lines using Javascript and using HTML 5 Canvas to display the two lines. A plunk is available here: Plunk - Intersection of two lines We continue from the last article and add a LineIntersection function and add prototype functions. This "class" will help us find the intersection points. The code is as follows:  function LineIntersection (config){ this.m1 = config.m1; this.b1 = config.b1; this.m2 = config.m2; this.b2 = config.b2; this.error = 0; this.marginOfError = 0.01; this.iterations = 0; this.maxIterations = 200; } LineIntersection.prototype.PrintData = function() { console.clear(); console.log("m1: " + this.m1 + " b1: " + this.b1 + " m2: " + this.m2 + " b2: " + this.b2); } LineIntersection.prototype.GetGuess = function(guess){ var newguess = ((this.b2 - this.b1) / (this.m1 - this.m2) + guess) / 2; return newguess; } LineIntersection.prototype.Y1 = function (guess){ return this.m1 * guess + this.b1; } LineIntersection.prototype.Y2 = function (guess){ return this.m2 * guess + this.b2; } LineIntersection.prototype.DeltaY = function (guess){ return Math.abs(this.Y1(guess) - this.Y2(guess)); } LineIntersection.prototype.FindIntersection = function(){ this.iterations = 0; if (this.m1 == this.m2) { alert("The two lines are parallel!"); return { x: "Infinity", y: "Infinity"}; } guess = Math.floor(Math.random() * 10 + 1); do { guess = this.GetGuess(guess); this.error = this.DeltaY(guess); if (this.iterations > this.maxIterations){ break; this.iterations = this.iterations + 1; } } while (this.error > this.marginOfError); return { x: guess.toFixed(2), y: this.Y1(guess).toFixed(2) } } //function LineIntersection  The intersection point is then calculated using the code in the following jQuery button click event handler: $("#btnIntercept").click(function(){
var m1,b1,m2,b2 = 0;

m1 = parseFloat($("#m1").val()); b1 = parseFloat($("#b1").val());
m2 = parseFloat($("#m2").val()); b2 = parseFloat($("#b2").val());

var myGraph = new Graph({
canvasId: 'Graph',
minX: -10,
minY: -10,
maxX: 10,
maxY: 10,
unitsPerTick: 1
});

myGraph.drawLine(m1, b1, 'blue', 3);

myGraph.drawLine(m2, b2, 'red', 4);

var lineIntersect = new LineIntersection({
m1: m1,
b1: b1,
m2: m2,
b2: b2
});

lineIntersect.PrintData();

var intersect = lineIntersect.FindIntersection();
console.log(intersect);
console.log(intersect.x);

myGraph.drawRect(intersect.x, intersect.y, 0.5, 0.5);

$("#detailsInfo").append("Intersection point: " + " X: " + intersect.x + " Y: " + intersect.y);  To plot a dot where the calculated intersection point the following code is used:  Graph.prototype.drawRect = function (x, y, width, height){ var context = this.context; this.transformContext(); context.strokeStyle = 'green'; context.fillRect(x - (width/2), y - (height/2), width, height); }  To move from object space coordinates to display coordinates we make use of the following helper function:  Graph.prototype.transformContext = function() { var context = this.context; // move context to center of canvas this.context.translate(this.centerX, this.centerY); /* * stretch grid to fit the canvas window, and * invert the y scale so that that increments * as you move upwards */ context.scale(this.scaleX, -this.scaleY); };  ## Sunday, 6 August 2017 ### Drawing intercepting lines with HTML 5 and Js - Part One I am working with a sample demo that will draw two lines and calculate the intersection. The demo will use Js and HTML 5 Canvas. I have made a Plunk available here: Canvas line drawing Plunk The image belows shows a rendering of two lines on the form :  y = f(x) = ax + b, y1 = x + 1, y2 = -x + 3  The HTML and Js code is below. I will in the later articles focus on calculating the interception with an iterative approximation method for the intercept. In a future article I will clean up the code and I will look on the code bits and look at Canvas functionality. Here is the code:  <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <script data-require="jquery@*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link data-require="bootstrap-css@*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" /> <link rel="stylesheet" href="style.css" /> <script src="script.js"></script> </head> <body> <h1>Intersection of two lines with Canvas and Js </h1> <fieldset> <label>y = mx + b</label> <br /><br /> <table> <tr> <td> <label for="m1">m1:</label> <input id="m1" type="text" style="width:50px" /></td> <td> <label for="b1">b1:</label> <input id="b1" type="text" style="width:50px" /></td> <td> <label for="slope2">m2:</label> <input id="m2" type="text" style="width:50px" /></td> <td> <label for="b2">b2:</label> <input id="b2" type="text" style="width:50px" /></td> </tr> <tr> <td><input id="btnGraph" type="button" value="Draw line" /></td> </tr> </table> <br /> <h3>Graph</h3> <canvas id="Graph" style="background:aliceblue;border:1px solid #AFAFAF" width="600" height="600"></canvas> </fieldset> <script> function Graph(config) { // user defined properties this.canvas = document.getElementById(config.canvasId); this.minX = config.minX; this.minY = config.minY; this.maxX = config.maxX; this.maxY = config.maxY; this.unitsPerTick = config.unitsPerTick; // constants this.axisColor = '#aaa'; this.font = '8pt Calibri'; this.tickSize = 20; // relationships this.context = this.canvas.getContext('2d'); this.rangeX = this.maxX - this.minX; this.rangeY = this.maxY - this.minY; this.unitX = this.canvas.width / this.rangeX; this.unitY = this.canvas.height / this.rangeY; this.centerY = Math.round(Math.abs(this.minY / this.rangeY) * this.canvas.height); this.centerX = Math.round(Math.abs(this.minX / this.rangeX) * this.canvas.width); this.iteration = (this.maxX - this.minX) / 1000; this.scaleX = this.canvas.width / this.rangeX; this.scaleY = this.canvas.height / this.rangeY; // draw x and y axis this.drawXAxis(); this.drawYAxis(); } Graph.prototype.drawXAxis = function() { var context = this.context; context.save(); context.beginPath(); context.moveTo(0, this.centerY); context.lineTo(this.canvas.width, this.centerY); context.strokeStyle = this.axisColor; context.lineWidth = 2; context.stroke(); // draw tick marks var xPosIncrement = this.unitsPerTick * this.unitX; var xPos, unit; context.font = this.font; context.textAlign = 'center'; context.textBaseline = 'top'; // draw left tick marks xPos = this.centerX - xPosIncrement; unit = -1 * this.unitsPerTick; while(xPos > 0) { context.moveTo(xPos, this.centerY - this.tickSize / 2); context.lineTo(xPos, this.centerY + this.tickSize / 2); context.stroke(); context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3); unit -= this.unitsPerTick; xPos = Math.round(xPos - xPosIncrement); } // draw right tick marks xPos = this.centerX + xPosIncrement; unit = this.unitsPerTick; while(xPos < this.canvas.width) { context.moveTo(xPos, this.centerY - this.tickSize / 2); context.lineTo(xPos, this.centerY + this.tickSize / 2); context.stroke(); context.fillText(unit, xPos, this.centerY + this.tickSize / 2 + 3); unit += this.unitsPerTick; xPos = Math.round(xPos + xPosIncrement); } context.restore(); }; Graph.prototype.drawYAxis = function() { var context = this.context; context.save(); context.beginPath(); context.moveTo(this.centerX, 0); context.lineTo(this.centerX, this.canvas.height); context.strokeStyle = this.axisColor; context.lineWidth = 2; context.stroke(); // draw tick marks var yPosIncrement = this.unitsPerTick * this.unitY; var yPos, unit; context.font = this.font; context.textAlign = 'right'; context.textBaseline = 'middle'; // draw top tick marks yPos = this.centerY - yPosIncrement; unit = this.unitsPerTick; while(yPos > 0) { context.moveTo(this.centerX - this.tickSize / 2, yPos); context.lineTo(this.centerX + this.tickSize / 2, yPos); context.stroke(); context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos); unit += this.unitsPerTick; yPos = Math.round(yPos - yPosIncrement); } // draw bottom tick marks yPos = this.centerY + yPosIncrement; unit = -1 * this.unitsPerTick; while(yPos < this.canvas.height) { context.moveTo(this.centerX - this.tickSize / 2, yPos); context.lineTo(this.centerX + this.tickSize / 2, yPos); context.stroke(); context.fillText(unit, this.centerX - this.tickSize / 2 - 3, yPos); unit -= this.unitsPerTick; yPos = Math.round(yPos + yPosIncrement); } context.restore(); }; Graph.prototype.drawEquation = function(equation, color, thickness) { var context = this.context; context.save(); context.save(); this.transformContext(); context.beginPath(); context.moveTo(this.minX, equation(this.minX)); for(var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) { context.lineTo(x, equation(x)); } context.restore(); context.lineJoin = 'round'; context.lineWidth = thickness; context.strokeStyle = color; context.stroke(); context.restore(); }; Graph.prototype.drawLine = function(slope, yintercept, color, thickness) { console.log("Inside drawline"); console.log("this.maxX: " + this.maxX + " this.maxY: " + this.maxY); var context = this.context; // draw x and y axis this.drawXAxis(); this.drawYAxis(); //context.clearRect(0, 0, this.canvas.width, this.canvas.height); context.save(); context.save(); this.transformContext(); console.log("this.minX: " + this.minX); console.log("this.iteration: " + this.iteration); console.log("yintercept: " + yintercept); console.log("slope:" + slope); context.beginPath(); context.moveTo(this.minX, slope * this.minX + yintercept); for(var x = this.minX + this.iteration; x <= this.maxX; x += this.iteration) { if (this.iteration % 200 == 0){ console.log("x: " + x + " y: " + (slope * x + yintercept)); } context.lineTo(x, slope * x + yintercept); } context.restore(); context.lineJoin = 'round'; context.lineWidth = thickness; context.strokeStyle = color; context.stroke(); context.restore(); }; Graph.prototype.transformContext = function() { var context = this.context; // move context to center of canvas this.context.translate(this.centerX, this.centerY); /* * stretch grid to fit the canvas window, and * invert the y scale so that that increments * as you move upwards */ context.scale(this.scaleX, -this.scaleY); }; </script> <script>$(document).ready(function(){

$("#btnGraph").click(function(){ var m1,b1,m2,b2 = 0; m1 = parseFloat($("#m1").val());
b1 = parseFloat($("#b1").val()); m2 = parseFloat($("#m2").val());
b2 = parseFloat($("#b2").val()); var myGraph = new Graph({ canvasId: 'Graph', minX: -10, minY: -10, maxX: 10, maxY: 10, unitsPerTick: 1 }); myGraph.drawLine(m1, b1, 'blue', 3); myGraph.drawLine(m2, b2, 'red', 4); //myGraph.drawEquation(function(x) { //return 1 * x; //}, 'red', 3); }); }); </script> </body> </html>  ## Wednesday, 2 August 2017 ### Calculating the square root in Javascript using the Babylonian method Calculating the square root in Javascript is easily done using Math.sqrt(n). But it can be entertaining to use an approximation method instead and build up an algorithm to calculate the square root. We will use the Babylonian method to approximate the square root using an iterative approximation method. The Babylonian method is described in Wikipedia here: Babylonian method. The following image shows how each step of a revised value for the square root is calculated. We calculate the square root of S by using an inital guess and then revise that step by adding that guess with S divided by the guess and dividing by 2. The revised value is then used again as the new guess value. We stop iterating when the margin of error is below a given treshold. In the calculus, x is the step guess value and e is the error. We start the calculation sample by adding in Bootstrap CSS and jQuery.  <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script data-require="jquery@*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link data-require="bootstrap-css@*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" /> </head> <body> <br /> <div class="container"> <h2>Find square root in JS with long division algorithm</h2> <hr /> <!-- html code here --> <h3>Estimate Square Root</h3> Enter Number: <input id="num" value="700" size="2" type="text" /> <br /> <input id="submitButton" value="Calculate" type="submit" /> <br /> <br /> <div id="details"></div> </div> <script type="text/javascript"> "use strict"; var x = 25; var guess = 9; var marginOfError = 0.1; var error = 0; var counter = 0; var htmlout = "";$(document).ready(function() {
// function code goes here
function getGuess(g) {
console.log(g);
var newguess = (g + x / g) / 2;
return newguess;
}
$('#submitButton').click(function() { // JavaScript code here console.clear(); counter = 0; x = parseFloat($('#num').val());
guess = Math.floor(Math.random() * x + 1);
error = Math.abs(guess * guess - x);
while (error >= marginOfError) {
guess = getGuess(guess)
error = Math.abs(guess * guess - x);
//console.log(guess);
counter += 1;
}
console.log('Count is ' + counter)
htmlout = "Square Root is " + guess.toFixed(2) + ". It took " + counter + " guesses";
$('#details').html(htmlout); }); }); </script> </body> </html>  Let us clean up the code using classes in Ecmascript 6 (ES6) and use Traceur to support the ES6 syntax.  <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script> <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script> <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script> <script data-require="jquery@*" data-semver="3.1.1" src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script> <link data-require="bootstrap-css@*" data-semver="4.0.0-alpha.4" rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.4/css/bootstrap.min.css" /> </head> <body> <br /> <div class="container"> <h2>Find square root in JS with long division algorithm</h2> <hr /> <!-- html code here --> <h3>Estimate Square Root</h3> Enter Number: <input id="num" value="700" size="2" type="text" /> <br /> <input id="submitButton" value="Calculate" type="submit" /> <br /> <br /> <div id="details"></div> </div> <script type="text/javascript"> "use strict"; class BabylonianSquareRootSolver { constructor(x_0, S, marginOfError = 0.1){ this.S = S; this.x_0 = x_0; this.marginOfError = marginOfError; } getRevisedSquareRoot (x_n, S){ var revisedValue = (x_n + (S/x_n)) / 2; return revisedValue; } calculateSqrt(){ var counter = 0; var error = 0; var guess = this.x_0; error = Math.abs(this.x_0 * this.x_0 - S); while (error >= marginOfError) { guess = this.getRevisedSquareRoot(guess, this.S) error = Math.abs(guess * guess - this.S); console.log(guess); counter += 1; if (counter > 10) break; } var result = { S : this.S, error : error, iterations : counter, root : guess }; return result; } } var S = 1; var guess = Math.floor(Math.random()*S); var marginOfError = 0.1; var error = 0; var counter = 0; var htmlout = "";$(document).ready(function() {
// function code goes here

$('#submitButton').click(function() { // JavaScript code here console.clear(); counter = 0; S = parseFloat($('#num').val());
guess = Math.floor(Math.random()*S);
var bab = new BabylonianSquareRootSolver(guess, S);

console.log(bab);
var res = bab.calculateSqrt();
htmlout = "Square Root is approximated to " + res.root.toFixed(2) + ". It took " + res.iterations
+ " iterations. The error for this approximation is: " + res.error.toFixed(4);
\$('#details').html(htmlout);
console.log(bab.calculateSqrt());

});
});
</script>
</body>

</html>



You can test out the code yourself with the following Plunk:
Babylonian method - Plunk Here is an image of the GUI: