
-----------------------------------
Homer_simpson
Wed Apr 14, 2010 7:00 pm

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.


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


-----------------------------------
SNIPERDUDE
Wed Apr 14, 2010 8:47 pm

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

-----------------------------------
Homer_simpson
Wed Apr 14, 2010 9:31 pm

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
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



-----------------------------------
ProgrammingFun
Sun Apr 18, 2010 2:33 pm

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"

-----------------------------------
Homer_simpson
Sun Apr 18, 2010 10:59 pm

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.
