Developer   Demos & Samples   Graphics Calculator

Graphics Calculator

Screenshot
This demo demonstrates what you need to do in order to create a graphics calculator, which can draw graphs of mathematics functions, calculate complicated mathematical expressions, solve systems of equations (with two or three variables) and convert physical units.

User interface

Moscrif SDK offers developers some predefined skins, which can be used to customise user interface. Thanks to these predefined skins, developers can use metro skin (skin normally used on Windows phone 7 devices) on all other supported platforms (Android, Bada, Symbian, iOS). Metro skin is adapted and can be used on various resolutions. All dimensions are calculated according to the screen resolution of the device. Also, all icons used in our application are in SVG format which retains the details of the graphics and all resolutions.
First part of our application, which users can see when they start the application, is Menu. It uses tileView element. Other parts of our application are managed by separate classes.


include "code://skin/skin.metro.ms" // creating Metro UI skin
var skin = new MetroSkin(); // applying skin to application
var app = new Application("",skin); app.onStart = function()
{
   // initialiation code
} app.init();
app.run();

 

Graph drawing


Before drawing the graph we have to change mathematic expression added by user, because user might write mathematic expressions in a form like: y = √(x) + cos(x) We have to change it to a form that can be usable in JavaScript exec function (something like: y = Math.sqrt(x) + Math.cos(x);). Our solution is very simple. We only need to return string and replace all mathematic functions by JavaScript functions.

Graph of the mathematic function is drawn point by point. Why? If it was not drawn this way, problem would appear with discrete graph (graph composed of isolated points). The most important function for calculating graph values is called calculateGraphVariables:

function calculateGraphVariables(equation) {
        var points = {
            x : new Array(),
            y : new Array(),
        }         //this function draws graph
        //unit is distance between two points on x-axis for which we calculate y values
        var unit = (System.width / this.zoom * 1.)/System.width * 2.0;
        var q = 0;
        var y,x;
        var dy;
        var dx;         //radius of the circle, which represents point on the graph
        var radius = 2.0;         //calculate y-values for required x-values
        while (q * unit < System.width / (this.zoom * 1.0)) {
            try {
                x = (System.width / (2.0 * this.zoom) - q * unit );
                y = eval ("x = " + x  + ";" + equation);
            }catch (err) {
                if(this.error.visible == false)
                    this.error.visible = true;
                break;
            }             //convert to screen coordinates
            dy = System.height / 2.0 + -1 * y * this.zoom;
            dx = System.width / 2.0 + x * this.zoom ;
            if(typeof dy != #integer)
                dy = dy.toInteger();
            if(typeof dx != #integer)
                dx = dx.toInteger();             //save values (left top corner of circle) for draw function
            points.x[q] = dx - 2;
            points.y[q] = dy - 2;
            q++;
        }         return points; }


calculateGraphVariables returns all values for one graph. Our calculator is able to draw up to four graphs.

function calculateGraphsVariables()
{
        this.graphsVariables = {
            points : new Array(),
        };         if (app.functionView.editor1.text) {
            this.graphsVariables.points[0] = this.calculateGraphVariables(this._equation1);
        }         if (app.functionView.editor2.text) {
            this.graphsVariables.points[1] = this.calculateGraphVariables(this._equation2);
        }         if (app.functionView.editor3.text) {
            this.graphsVariables.points[2] = this.calculateGraphVariables(this._equation3);
        }
        if (app.functionView.editor4.text) {
            this.graphsVariables.points[3] = this.calculateGraphVariables(this._equation4);
        } }

After these two functions we have all the values for graph drawing. A drawing graph function can be performed up to 60 times in one second. However, it has to be coded as simply as possible because calculating values in“onDraw” function would be too time-consuming for rendering.

 

function drawGraph(canvas, equation, paint)
{
        for (var q = 0; q < this.graphsVariables.points[equation].x.length; q++) {
canvas.drawOval(this.graphsVariables.points[equation].x[q], this.graphsVariables.points[equation].y[q], this.graphsVariables.points[equation].x[q] + 4, this.graphsVariables.points[equation].y[q] + 4 , paint);
        } }

 

Solving the system of equations

All the forms and functions associated with solving the system of equations are contained in LinearEquations class. To solve the system of equations we use Gaussian elimination. Gaussian elimination is an algorithm for solving systems of linear equations, which can be also used to find the rank of a matrix, to calculate the determinant of a matrix, and to calculate the inverse of an invertible square matrix.

Input of this algorithm is a matrix, which contains all numbers from system of equations.
How does it work?

System of equations:

5x + z = 9
x - z + y = 6
2x - y + z = 0

matrix:


The process of Gaussian elimination has two parts. The first part (Forward Elimination) reduces a given system to triangular form. This is accomplished through the use of elementary row operations. The second step uses back substitution to find the solution of the system above.

Example:

1) Rewrite system to form as:

2) Eliminate x variable from second and third row

3) Eliminate y from third row

4) Final system is:

5) Now, we can use back substitution to find the solution of the system:

Our algorithmic implementation uses three functions: gauss, createTriangularMatrix and calculateVariables(). Function gauss calls other two functions and shows the result of the equation. Other two functions are self-explanatory from their name.

function gauss()
{     this.createTriangularMatrix();
    this.calculateVariables();     //skow result
    this.resultView.visible = true;
    this.resultView.invalidate();
} function createTriangularMatrix()
{
    //convert source matrix to triangular matrix (all values above the main diagonal are zero)
    var coefficient;
    //go throw rows
    for (var i = 0; i         //go throw columns
        for (var j = i + 1; j             if(this.gaussSet[i][i].toFloat() == 0) {
                this.info.text = "Fields on the diagonal mustn't be zero!";
                this.info.invalidate();
                this.info.visible = true;
                return 1;
            }
            coefficient = -1 * this.gaussSet[j][i].toFloat() / this.gaussSet[i][i].toFloat();
            //calculate all rows
            //add value to all other numbers at the row
            for (var q = 0; q                 this.gaussSet[j][q] += this.gaussSet[i][q] * coefficient;
            }
        }
    }
} //calculate variables (we goes fram the end fo matrix and calculate variables)
function calculateVariables()
{
    var coefficient;
    for (var i = this.equations - 1; i > 0 - 1; i--) {
        //calculate other members
        coefficient = 0;         //count all known variables
        for (var q = i + 1; q         {
            coefficient += this.gaussSet[i][q] * this.solutions[q];
        }         //if value on the diagonal of matrix is zero. In this case we would multiply by zero, what's problem
        if(this.gaussSet[i][i].toFloat() == 0) {
            this.info.text = "Equation has no or infinitely many solutions!";
            this.info.invalidate();
            this.info.visible = true;
            return 1;
        }         //calculate value for another variables (if we known y and z (y = 1; z = 2) and equation is 9 = 2x + 2y + 3z then x is: (9 - (2 * 1 + 3 * 2)/2) -> 0.5
        this.solutions[i] = (this.gaussSet[i][this.equations] - coefficient) / this.gaussSet[i][i] ;
    }
}

Calculator

Calculator calculates mathematic expressions and delivers their results. It consists of keyboard and textBoxes for mathematic expressions and their results.
Expressions solving is executed by function Solve which uses javascript function called Exec. (see more: http://www.w3schools.com/jsref/jsref_regexp_exec.asp).

Unit converter

From all the features included in this Calculator bundle, Unit converter is definitely the easiest to create.Two functions are made for every supported physical quantity. First is init[quantity name], which adds all supported units to the main list view and second is calculate[quantity name], which recalculates all values when any value is changed.
Functions initTime and calculateTime:

function calculateTime(seconds,unit)
{
  if(unit != "days") {
  var days = seconds / (60 * 60 * 24);
  this.days.textBox.text = days.toString();
  }
  if(unit != "hours") {
  var hours = seconds / (60 * 60);
  this.hours.textBox.text = hours.toString();
  }
  ...
  if(unit != "seconds") {
  this.seconds.textBox.text = seconds.toString();
  }
}

License

This article and all associated source codes and files are licensed under The BSD License

Write a Comment (0)
Subject
 
Comment