You are to imagine a square-section rod of material has been suddenly placed in a hot furnace. The heat flows inward, raising the temperature. At first only the surface is hot, but the heat 'soaks' in and it starts to look like the image here. Visually blues 'feel' cold, and reds 'feel' hot, so a colour coding used as here greatly improves your appreciation of what is happening.
At steel works, such a furnace is therefore referred to as a 'soaking pit', where the ingot is raised to a uniform temperature ready to pass through the rolling mill.
It is easy programmatically to express a range of numbers with colours spread between two limiting colours, say from red to bloe, by using lines like-
' x has values from x.min to x.max range =x.max -x.min c =int( 256 *(x -x.min) /x.range) col$ =str$( c) +" 0 " +str$( 255 -c) #w.g1 "color "; col$These colour ranges are pretty limiting however. To represent temperature with a suitable colour-range is done here by using an existing colour-bar as a look-up table. You can choose any that you like off the 'net, or create your own. Scale its length to whatever colour/value resolution you want. Just use your favoured painting package to scale it to say 256x10, if to be used in this program. Thanks to KCDan for the method used, which works in LB or JB. If for LB-only I'd use the API method, but there is little speed penalty. I could of couse have read the colour pixel values directly out of the colour-range bitmap, but I needed to display it anyway to show the scaling used! It is also a slight problem done by direct-reading that there are different BMP formats with the data at different positions. I could alternatively have written a sub-program to generate a string of data statements representing the appropriate RGB string for LB to use. You can then copy/paste these data statements into a program, but this makes it rather long and inscrutable, especially if using 256 or more colours....
This is the one I used here-
And some others...
---
---
Notice it can be helpful to have a different colour- eg black- to show clearly values of zero, and the intermediate black lines can also help to read off values.
Others I sometimes use are created with graduation tools, or copied from published images. Multiple-repeat scales give finer visual resolution, but at the expense of making colour values not represent a unique temperature. It may also be worth doing a log transform, since temperature gradients are often exponential. This emphasises and exaggerates changes near the bottom of a scale, but compresses values higher on the scale.
These colour look-ups may of course be of different length, to suit your scale intervals. You can give the user the opportunity to choose the range of choice, and display it beside the graph.
By altering the starting conditions, you can model instead a slab heated only on one edge, or a slab with a heat source at the centre. Higher resolutions are of course easy to do. The 40x40 gives adequate resolution, and by saving images at minute intervals but playing the animation at one frame per second works nicely.
The same simulation can be mdified to represent spread of disease; diffusion of gases; etc.
This could be implemented by two nested for-next loops visiting all points systematically. This would however requuire a second temporary grid to hold the new values, since each cell has to refer to its PRESENT four neighbours, rather than UPDATED neighbours. Instead I found it easier to update cells at random, which also make the visual display more interesting during the calculation stage. It is still rather slow, so I save every 10 seconds and make the animation frame-by-frame be played back at say 1 frame per sec.
The program saves the whole LB window & reloads it, thus avoiding the big redraw & memory penalty, at the same time as it saves the part representing the slab. The ImageMagick lines are remmed out, since I used the command line for this page.
WindowWidth = 544 WindowHeight =660 nomainwin graphicbox #w.gb1, 20, 20, 500, 580 open "Laplace solution- slab heated at sides." for graphics_nsb_nf as #w #w "trapclose [quit]" #w.gb1 "down ; fill lightgray" loadbmp "scr", "repeat.bmp" #w.gb1 "drawbmp scr 110 20" unloadbmp "scr" #w.gb1 "up ; goto 45 125 ; down ; color black ; backcolor black ; boxfilled 435 515" #w.gb1 "backcolor lightgray ; font courier_new 15 bold" #w.gb1 "up ; goto 104 15 ; down" #w.gb1 "\Hot . . . . . . . Cold" #w.gb1 "up ; goto 104 50 ; down" #w.gb1 "\.200 . 100 . 40 . 20 log scale." #w.gb1 "up ; goto 94 74 ; down" #w.gb1 "\255 . . .120 . . . 10 lin scale." #w.gb1 "place 74 68 ; backcolor yellow ; circlefilled 6" #w.gb1 "flush" dim slab1( 40, 40) dim colour$( 255) global n: n =0 call getColValues call boundary timer 100, saveBmp #w.gb1 "size 7" for i =1 to 1000000 x.rand =int( 41 *rnd( 1)) y.rand =int( 41 *rnd( 1)) if x.rand <>0 and x.rand <>40 and y.rand <>0 and y.rand <>40 then average =0 average =average +slab1( x.rand -1, y.rand) +slab1( x.rand +1, y.rand) +slab1( x.rand, y.rand -1) +slab1( x.rand, y.rand +1) average =int( average /4) slab1( x.rand, y.rand) =average end if #w.gb1 "color "; colour$( int( 45 *( log( 1 +slab1( x.rand, y.rand))))) #w.gb1 "set "; 40 +x.rand *10; " "; 520 -y.rand *10 scan next i timer 0 IM$ ="convert +matte -resize 205x205 -delay 200 screens\*.bmp anim.gif" print IM$ 'run "cmd.exe /c "; chr$( 34); IM$; chr$( 34), HIDE ' Give it 30 seconds to execute (may not be enough for large images) 'timer 30000, [on] ' wait '[on] ' timer 0 wait end sub saveBmp timer 0 #w.gb1 "getbmp sca 0 0 500 580" #w.gb1 "getbmp sc 35 115 410 410" name$ ="screens\slab1side" +right$( "000" +str$( n), 3) +".bmp" bmpsave "sc", name$ n =n +1 timer 30000, saveBmp #w.gb1 "cls" #w.gb1 "drawbmp sca 0 0" unloadbmp "sc" unloadbmp "sca" end sub Function KCGetPixel$( x, y) 'x, y = window coordinates Thanks KCDan!! #w.gb1, "Getbmp pixel "; 110 +x; " "; 22 +y; " 1 1" 'A 1x1 bitmap, contains exactly 1 pixel #w.gb1 "color white ; set "; 110 +x; " "; 25 +y Bmpsave "pixel", "kcGetPixelData.datkc" 'Save that one pixel as a temporary bmp file Open "kcGetPixelData.datkc" for Binary as #kc 'Open that one pixel bmp file as a binary file Seek #kc, 66 'Blue Info b =Asc( Input$( #kc, 1)) 'Blue Seek #kc, 67 'Green Info g =Asc( Input$( #kc, 1)) 'Green Seek #kc, 68 'Red Info r =Asc( Input$( #kc, 1)) 'Red Close #kc Kill "kcGetPixelData.datkc" 'Delete the temporary bmp file KCGetPixel$ =r; " "; g; " "; b 'Place the values in a string 'print KCGetPixel$ End Function sub getColValues for v =1 to 256 colour$( v -1) =KCGetPixel$( 256 -v, 5) next v end sub sub boundary for i =0 to 40 slab1( i, 0) =255 slab1( i, 40) =255 slab1( 0, i) =255 slab1( 40, i) =255 next i #w.gb1 "size 7" for x =0 to 40 for y =0 to 40 #w.gb1 "color "; colour$( int( 45 *( log( 1 +slab1( x, y))))) #w.gb1 "set "; 40 +x *10; " "; 520 -y *10 next y next x call saveBmp end sub [quit] close #w end