2D Data Plotting
To demonstrate the scalar to RGB colormap from the previous article, I put together a little demo showing how to visualize some 2D scalar field. Here I am plotting \(f(x,y)=1-0.5(x^2+y^2)\). This function varies radially from 1 at the origin to 0 in the corners of \([-1,-1]:[1,1]\) domain. Ideally, you would want to visualize the results by performing contouring. But in the absence of an actual contouring algorithm (the Visualization Toolkit book is a great reference) we obtain insight into the data by flooding each computational cell with the cell primary value. You can use the sliders below the change the numbers of levels and the cell spacing.
Source Code
You can see the entire source code by opening the following link and using “Right click -> view source”. As you can see, the entire code is only 80 lines long. We first specify the needed HTML elements, mainly <canvas> and <form>:
<div style="padding-left: 2em;text-align:left"> <canvas id="canvas" width="400" height="400" style="border: 2px solid black;margin-bottom: 0.25em;"> Your browser does not support canvas </canvas> <form action="null" method="post"> Contours: <input type="range" id="nc" min="1" max="250" value="25" oninput="replot();" ><span id="span_nc"></span><br> ni: <input type="range" id="ni" min="5" max="80" value="40" style="width:100px" oninput="replot();" ><span id="span_ni"></span><br> nj: <input type="range" id="nj" min="5" max="80" value="40" style="width:100px" oninput="replot();" ><span id="span_nj"></span><br> </form> </div>
As you can see, whenever one of the inputs changes, we call function replot(). We also definite another function, called init() which is called just once to set up the transformation.
<script> init(); replot(); /*uses form data to regenerate the plot*/ function replot() { var nc=document.getElementById("nc").value; var ni=document.getElementById("ni").value; var nj=document.getElementById("nj").value; document.getElementById("span_nc").innerHTML="("+nc+")"; document.getElementById("span_ni").innerHTML="("+ni+")"; document.getElementById("span_nj").innerHTML="("+nj+")"; plot(ni,nj,nc); } var ctx; /*gets context and sets transformation*/ function init() { var c = document.getElementById("canvas"); ctx = c.getContext("2d"); var w=c.width; var h=c.height; /*transform to set canvas range from (-1,-1) in bottom left to (1,1) in top right*/ ctx.translate(0.5*w,0.5*h); ctx.scale(0.5*w,-0.5*h); ctx.lineWidth=2/w; }
Finally, the actual plotting is done in the function plot(). This function takes as its inputs the number of cells in the x and y direction, as well as the number of banded levels. For each cell, ranging from (x,y) to (x+di,y+dj), we compute the function $latex f=1-0.5(x_c^2+y_c^2)$ at the cell centroid. The color is converted to a banded value using b = Math.round(z*nlev)/nlev. This scalar is then converted to RGB using the method described in the previous article, Converting Scalars to RGB. The color is used to “flood” the cell, by painting a solid filled rectangle. You may notice that the width of the rectangle is slightly larger than di and dj. This is done to overlap the rectangles, to avoid gaps. The code is again below.
/*plots a scalar function f=1-0.5(x^2+y^2) on domain (-1,-1):(1,1)*/ function plot(ni,nj,nlev) { ctx.strokeRect(-1,-1,2,2); //add border var di = 2/(ni-1); //cell spacing, total length=2 var dj = 2/(nj-1); var x0 = -1; var y0 = -1; for (var j=0;j<nj;j++) for (var i=0;i<ni;i++) { var x = x0+i*di; //this is the origin of the cell var y = y0+j*dj; var xc = x+0.5*di; //this is the centroid of the cell var yc = y+0.5*dj; var z = 1-0.5*(xc*xc+yc*yc); //evaluate at the centroid var b = Math.round(z*nlev)/nlev; //banded value var a=(1-b)/0.25; //invert and group var X=Math.floor(a); //this is the integer part var Y=Math.floor(255*(a-X)); //fractional part from 0 to 255 switch(X) { case 0: r=255;g=Y;b=0;break; case 1: r=255-Y;g=255;b=0;break; case 2: r=0;g=255;b=Y;break; case 3: r=0;g=255-Y;b=255;break; case 4: r=0;g=0;b=255;break; } ctx.fillStyle = "rgb("+r+","+g+","+b+")"; ctx.fillRect(x,y,di*1.2,dj*1.2); //1.2x to avoid gaps } }
Bonjour j ai un petit problème au niveau de simulation de l equation de la place en 2 dimension je trouve que la solution u du système linéaire est constante et quand je calcul l inverse de la matrice j ai la meme valeur qui se repete sachant que je travail avec la méthode des éléments finis et les condition au limite u=0 j ai besoin de votre aide merci d avance
–zguir
I managed to understand you have problems solving 2d laplace heat eq (?) at the step where you solve the system of linear eqs. I would recommend to research the TDMA line-by-line solving and its application to 2d domains.