Computer Science Canada Electric fields |
Author: | Homer_simpson [ Wed Apr 14, 2010 7:00 pm ] |
Post subject: | Electric fields |
just a demonstration that net force at a position in space due to electric fields is the sum of all forces at that position. and that electric fields grow inversly proportional to the square of distance in space. controls: clicking the mouse will move the currently selected charge(the one with green halo around it) holding shift and clicking the mouse will create a new charge in space. page up/page down scrolls through charges up arrow/ downarrow increase or decrease the charge on current particle 1 / 2 increase or decrease resolution of the field enter will alter the rendering mode(there are 2 modes) it runs superslow on my crappy netbook probably would run faster on your desktop. Quote: View.Set ("graphics:max;max,nobuttonbar,offscreenonly")
var res := 20 var maxp := 3 var ps : boolean := false var dmode : boolean := false procedure darrow (x1, y1, x2, y2, hsize : real, c1, c2, th : int) Draw.ThickLine (round (x1), round (y1), round (x2), round (y2), th, c2) var t : real if abs (x2 - x1) > 0 then t := arctand ((y2 - y1) / (x2 - x1)) if (x2 - x1) < 0 then t := 180 + t end if else t := (y2 - y1) * 90 end if drawline (round (x2), round (y2), round (x2 - (hsize * cosd (t + 45))), round (y2 - (hsize * sind (t + 45))), c2) drawline (round (x2), round (y2), round (x2 - (hsize * cosd (t - 45))), round (y2 - (hsize * sind (t - 45))), c2) end darrow const EC := 160000 function distance (x1, y1, x2, y2 : real) : real result sqrt (((x2 - x1) ** 2) + ((y2 - y1) ** 2)) end distance type chrg : record x, y, q : real exist : boolean end record type point : record x, y : real end record var plist : array 1 .. 100 of chrg var chars : array char of boolean %%%%%%%%%%%%%initialize%%%%%%%%%%% for i : 1 .. upper (plist) plist (i).exist := false end for colorback (black) cls var currentP : int := 3 plist (1).exist := true plist (1).x := 101 plist (1).y := 101 plist (1).q := 10 plist (2).exist := true plist (2).x := 501 plist (2).y := 501 plist (2).q := -20 plist (3).exist := true plist (3).x := 101 plist (3).y := 501 plist (3).q := 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% var netF : point var rad, mag : real var mx, my, mb : int ps := true loop if ps then for xx : 1 .. maxx by res for yy : 1 .. maxy by res netF.x := 0 netF.y := 0 %%%%summing forces%%%% for i : 1 .. upper (plist) if plist (i).exist then rad := distance (xx, yy, plist (i).x, plist (i).y) if plist (i).q > 0 then drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 12) elsif plist (i).q = 0 then drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 2) else drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 9) end if if i = currentP then drawoval (round (plist (i).x), round (plist (i).y), 12, 12, 10) end if if abs (rad) > 4 then mag := ((plist (i).q * EC) / (rad) ** 2) netF.x += mag * ((xx - plist (i).x) / rad) netF.y += mag * ((yy - plist (i).y) / rad) end if end if end for %%%%summing forces%%%% if dmode then if sqrt ((netF.x ** 2) + (netF.y ** 2)) > 0 and sqrt ((netF.x ** 2) + (netF.y ** 2)) < 3000 then darrow (xx, yy, xx + (((res * .3) + (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100)) * netF.x / sqrt ((netF.x ** 2) + (netF.y ** 2))), yy + (((res * .9) + (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100)) * netF.y / sqrt ((netF.x ** 2) + (netF.y ** 2))), (res * .1), 9, 54 - ((round (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100) mod 16)), 1) end if else if sqrt ((netF.x ** 2) + (netF.y ** 2)) < 100 then darrow (xx, yy, xx + netF.x, yy + (netF.y), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 9, 12, 1) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 200 then darrow (xx, yy, xx + (netF.x / 3), yy + (netF.y / 3), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 10, 10, 2) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 300 then darrow (xx, yy, xx + (netF.x / 4), yy + (netF.y / 4), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 11, 11, 3) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 400 then darrow (xx, yy, xx + (netF.x / 5), yy + (netF.y / 5), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 12, 12, 4) end if end if end for end for View.Update cls ps := false end if mousewhere (mx, my, mb) Input.KeyDown (chars) if chars (chr (200)) then plist (currentP).q += 1 ps := true elsif chars (chr (208)) then plist (currentP).q -= 1 ps := true end if if chars (chr (10)) then dmode := not dmode play ("1b") ps := true end if if chars (chr (201)) then if currentP > 1 then currentP := currentP - 1 play ("8b") ps := true end if elsif chars (chr (209)) then if currentP < maxp then currentP := currentP + 1 play ("8d") ps := true end if end if if chars ('1') then if res > 10 then res -= 5 ps := true end if elsif chars ('2') then if res < maxy div 2 then res += 5 ps := true end if end if if mb not= 0 then ps := true if chars (chr (180)) then if currentP < upper (plist) then currentP += 1 if maxp < currentP then maxp := currentP end if end if plist (currentP).exist := true plist (currentP).q := 1 plist (currentP).x := mx plist (currentP).y := my play ("9c") ps := true else plist (currentP).x := mx plist (currentP).y := my end if end if end loop |
Author: | SNIPERDUDE [ Wed Apr 14, 2010 8:47 pm ] |
Post subject: | RE:Electric fields |
Wow, that was really cool! Had to turn down the resolution of the field a bit for it to run more in real-time though. +bits |
Author: | Homer_simpson [ Wed Apr 14, 2010 9:31 pm ] |
Post subject: | Re: Electric fields |
i had made a stupid mistake of drawing the circles for charges too manytimes inside nested loop so heres the fixed version Quote: View.Set ("graphics:max;max,nobuttonbar,offscreenonly")
var res := 20 var maxp := 3 var ps : boolean := false var dmode : boolean := false procedure darrow (x1, y1, x2, y2, hsize : real, c1, c2, th : int) Draw.ThickLine (round (x1), round (y1), round (x2), round (y2), th, c2) var t : real if abs (x2 - x1) > 0 then t := arctand ((y2 - y1) / (x2 - x1)) if (x2 - x1) < 0 then t := 180 + t end if else t := (y2 - y1) * 90 end if drawline (round (x2), round (y2), round (x2 - (hsize * cosd (t + 45))), round (y2 - (hsize * sind (t + 45))), c2) drawline (round (x2), round (y2), round (x2 - (hsize * cosd (t - 45))), round (y2 - (hsize * sind (t - 45))), c2) end darrow const EC := 160000 function distance (x1, y1, x2, y2 : real) : real result sqrt (((x2 - x1) ** 2) + ((y2 - y1) ** 2)) end distance type chrg : record x, y, q : real exist : boolean end record type point : record x, y : real end record var plist : array 1 .. 100 of chrg var chars : array char of boolean %%%%%%%%%%%%%initialize%%%%%%%%%%% for i : 1 .. upper (plist) plist (i).exist := false end for colorback (black) cls var currentP : int := 3 plist (1).exist := true plist (1).x := 101 plist (1).y := 101 plist (1).q := 10 plist (2).exist := true plist (2).x := 501 plist (2).y := 501 plist (2).q := -20 plist (3).exist := true plist (3).x := 101 plist (3).y := 501 plist (3).q := 15 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% var netF : point var rad, mag : real var mx, my, mb : int ps := true loop if ps then for xx : 1 .. maxx by res for yy : 1 .. maxy by res netF.x := 0 netF.y := 0 %%%%summing forces%%%% for i : 1 .. upper (plist) if plist (i).exist then rad := distance (xx, yy, plist (i).x, plist (i).y) if abs (rad) > 4 then mag := ((plist (i).q * EC) / (rad) ** 2) netF.x += mag * ((xx - plist (i).x) / rad) netF.y += mag * ((yy - plist (i).y) / rad) end if end if end for %%%%summing forces%%%% if dmode then if sqrt ((netF.x ** 2) + (netF.y ** 2)) > 0 and sqrt ((netF.x ** 2) + (netF.y ** 2)) < 3000 then darrow (xx, yy, xx + (((res * .3) + (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100)) * netF.x / sqrt ((netF.x ** 2) + (netF.y ** 2))), yy + (((res * .9) + (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100)) * netF.y / sqrt ((netF.x ** 2) + (netF.y ** 2))), (res * .1), 9, 54 - ((round (sqrt ((netF.x ** 2) + (netF.y ** 2)) / 100) mod 16)), 1) end if else if sqrt ((netF.x ** 2) + (netF.y ** 2)) < 100 then darrow (xx, yy, xx + netF.x, yy + (netF.y), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 9, 12, 1) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 200 then darrow (xx, yy, xx + (netF.x / 3), yy + (netF.y / 3), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 10, 10, 2) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 300 then darrow (xx, yy, xx + (netF.x / 4), yy + (netF.y / 4), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 11, 11, 3) elsif sqrt ((netF.x ** 2) + (netF.y ** 2)) < 400 then darrow (xx, yy, xx + (netF.x / 5), yy + (netF.y / 5), sqrt ((netF.x ** 2) + (netF.y ** 2)) / 10, 12, 12, 4) end if end if end for end for for i : 1 .. upper (plist) if plist (i).exist then if i = currentP then drawoval (round (plist (i).x), round (plist (i).y), 12, 12, 10) end if if plist (i).q > 0 then drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 12) elsif plist (i).q = 0 then drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 2) else drawfilloval (round (plist (i).x), round (plist (i).y), round (10 + plist (i).q / 10), round (10 + plist (i).q / 10), 9) end if end if end for View.Update cls ps := false end if mousewhere (mx, my, mb) Input.KeyDown (chars) if chars (chr (200)) then plist (currentP).q += 1 ps := true elsif chars (chr (208)) then plist (currentP).q -= 1 ps := true end if if chars (chr (10)) then dmode := not dmode play ("1b") ps := true end if if chars (chr (201)) then if currentP > 1 then currentP := currentP - 1 play ("8b") ps := true end if elsif chars (chr (209)) then if currentP < maxp then currentP := currentP + 1 play ("8d") ps := true end if end if if chars ('1') then if res > 10 then res -= 5 ps := true end if elsif chars ('2') then if res < maxy div 2 then res += 5 ps := true end if end if if mb not= 0 then ps := true if chars (chr (180)) then if currentP < upper (plist) then currentP += 1 if maxp < currentP then maxp := currentP end if end if plist (currentP).exist := true plist (currentP).q := 1 plist (currentP).x := mx plist (currentP).y := my play ("9c") ps := true else plist (currentP).x := mx plist (currentP).y := my end if end if end loop |
Author: | ProgrammingFun [ Sun Apr 18, 2010 2:33 pm ] |
Post subject: | RE:Electric fields |
WOW, this is an amazing program... Was this for a project? Wouldn't it have been more rewarding in another language? It runs slow on my XP computer too :mrgreen" |
Author: | Homer_simpson [ Sun Apr 18, 2010 10:59 pm ] |
Post subject: | Re: Electric fields |
it wan't really a school project. i was inspired by watching mit physics lectures by walter lewing(they're free). but you are right it does run slow on turing, that's why i stopped working on it in turing i've made a c++ version with more capability and higher resolution but i haven't really setup a user input properly, i'll post it anyways, i'll complete it later. |