A web based Vector Feild Plotter (2D) written in Javascript and HTML Canvas (With source code)

Show Axes
Show Markings
Plot a Vector Field:






 

Guide

  • The box on the right houses the controls to show or hide the axes and the markings on the axes.
  • The  2D vector function is to be specified using the input boxes inside the box on the left side (i and j components separately). The expressions used to specify the components should be valid javascript expressions in variables x and y that evaluates to a number (number literals can also be included).
  • If the vectors the represent the field graphically are too big or short, their sizes can be adjusted using the range controls in the box on the left side. Use fine control for functions with small values (for example x+y) and the coarse control for large values (for example x*y*y).

The Source Code

The following is the full code for an HTML web page that implements the Vector Field Plotter:

<html>
<head><title>Vector Field Plotter</title></head>
<body onload="draw();" style="background-color: azure;">
<div>

<div style="float: left;">
<canvas height="500" id="VFS_Canvas" style="background-color: white; border: 5px solid black; margin: 20px;" width="500"></canvas>
    </div>
<script>
    var c = document.getElementById("VFS_Canvas"); //get canvas object
    ctx = c.getContext("2d"); // get context (the drawing object)
    var width = c.width, height = c.height; //get the width and height of the canvas
    
    //convert to a coordinate system with origin at the center and positive y axis pointing upwards
    ctx.scale(10,-10);
    var w = width/10,h =height/10; //width and height according to scaled system
    ctx.translate(w/2,-h/2);
    
    var vec_scale=1/(-Number(document.getElementById("scale_value_coarse").value)-Number(document.getElementById("scale_value_fine").value)); //relative length of feild vectors
    
    //draw axes with markings
    function drawAxes()
    {
        ctx.lineWidth = 0.1;
        if((document.getElementById("cb_axes")).checked==true)
        {
            ctx.beginPath();
            ctx.strokeStyle = "#505050";
            ctx.moveTo(-w/2,0);
            ctx.lineTo(w/2,0);
            ctx.moveTo(0,h/2);
            ctx.lineTo(0,-h/2);
            ctx.stroke();
        }
        if((document.getElementById("cb_markings")).checked==true)
        {
            var i;
            ctx.beginPath();
            ctx.strokeStyle = "#505050";
            for(i = 10; i < w/2 ; i+=10)
            {
                ctx.moveTo(i,0.5);
                ctx.lineTo(i,-0.5);
                
                ctx.moveTo(-i,0.5);
                ctx.lineTo(-i,-0.5);
                
                ctx.font = "1.5px Calibri";
                ctx.save();
                ctx.scale(1,-1);
                ctx.fillText(i.toString(),i,1.2);
                ctx.fillText((-i).toString(),-i,1.2);
                ctx.restore();
            }
            for(var i = 10; i < h/2 ; i+=10)
            {
                ctx.moveTo(0.5,i);    ctx.lineTo(-0.5,i);
                ctx.moveTo(0.5,-i);   ctx.lineTo(-0.5,-i);
                
                ctx.font = "1.5px Calibri";
                ctx.save();
                ctx.scale(1,-1);
                ctx.fillText(i.toString(),0.6,-i);
                ctx.fillText((-i).toString(),0.6,i);
                ctx.restore();
            }
            ctx.stroke();
        }
    }
    function drawArrowHead(x,y,i,j)
    {
        ctx.save();
        ctx.translate(x+vec_scale*i,y+vec_scale*j);
        ctx.rotate((j<0)?-Math.acos(i/Math.sqrt(i**2+j**2)):Math.acos(i/Math.sqrt(i**2+j**2)));
        ctx.moveTo(0,0);    ctx.lineTo(-0.5,0.5);
        ctx.moveTo(0,0);    ctx.lineTo(-0.5,-0.5);
        ctx.restore();
    }
    function drawVectors()
    {
        var x,y,i,j;
        ctx.lineWidth=0.1;
        ctx.beginPath();
        for(x = -(w*1.5)/2; x<=(w*1.5)/2;x+=2.5)
        {
            for(y=-(h*1.5)/2;y<=(h*1.5)/2;y+=2.5)
            {
                i = eval(document.getElementById("vec_i").value);
                j = eval(document.getElementById("vec_j").value);
                if(Math.abs(i)<0.01 && Math.abs(j)<0.01)    continue;
                ctx.moveTo(x,y);
                ctx.lineTo(x+vec_scale*i,y+vec_scale*j);
                drawArrowHead(x,y,i,j);
            }
        }
        ctx.strokeStyle = "#904010";
        ctx.stroke();
    }
    //draw everything (this function calls all other draw functions)
    function draw()
    {
        vec_scale=1/(-Number(document.getElementById("scale_value_coarse").value)-Number(document.getElementById("scale_value_fine").value));
            
        ctx.clearRect(-w/2,h/2,w,-h); //clear the canvas 
        drawAxes();
        drawVectors();
    }
    
</script>
    <div style="background-color: aliceblue; border: 5px solid black; float: right; margin: 20px; padding: 20px;">
        <input checked="" id="cb_axes" onclick="draw();" type="checkbox" /> Show Axes 

        <input checked="" id="cb_markings" onclick="draw();" type="checkbox" /> Show Markings 

    </div>
<div style="background-color: aliceblue; border: 5px solid black; float: right; margin: 20px; padding: 20px;">
        Plot a Vector Field:

        <label><b>V</b>(x,y) =</label> 

        <div style="margin: 4px;">
<input id="vec_i" type="text" value="-y" /><label><b> i</b> +</label></div>
<div style="margin: 4px;">
<input id="vec_j" type="text" value="x-y" /><label><b> j</b></label></div>
<input onclick="draw();" style="margin: 4px;" type="button" value="Update" />

        <div style="background-color: cornsilk; border: 2px solid black; margin: 4px;">
            <label style="margin: 2px;">Vector Size (coarse):</label>

            <input id="scale_value_coarse" max="0" min="-500" onchange="draw();" step="1" style="margin: 4px;" type="range" value="0" />

            <label style="margin: 2px;">Vector Size (fine):</label>

            <input id="scale_value_fine" max="-1" min="-25" onchange="draw();" step="0.5" style="margin: 4px;" type="range" value="-10" />

            <label style="font-family: calibri; padding: 4px;">
        If the vectors are still too short or large,
 try multiplying your expression by a constant.
        </label>
        </div>
</div>
</div>
</body>
</html>

Comments

  1. Hello thanks man the opengl glut for c++ really helped me alot but it would have been cooler if you posted it in YouTube please make more c++ opengl glut videos ;you the only guy in YouTube who posts c++, opengl, glut videos ,,,pls bro post more on this subject...thanks

    ReplyDelete

Post a Comment

Popular posts from this blog

Setting up a first person camera in OpenGL to move around in your 3D world

Science with OpenGL | #1 | Superposition of two waves