
-----------------------------------
zylum
Sun Jan 15, 2006 11:57 pm

[source] jello
-----------------------------------
this is an spin off from my string/chain source... its a completely different effect so i decided to make a new thread  :wink: 

setscreen ("graphics:max;max,offscreenonly")

type Node :
    record
        x, y, vx, vy : real
    end record

const g := -0.1
const wind := -0.0
const N := 9
const d := 100
const k := 0.08
const decay := 0.98
const radius := 8

var nodes : array 1 .. N of Node
for i : 1 .. N
    if i = 1 then
        nodes (i).x := maxx / 2
        nodes (i).y := maxy / 2
    else
        nodes (i).x := maxx / 2 + cosd (360 / N * i) * d
        nodes (i).y := maxy / 2 + sind (360 / N * i) * d
    end if
    nodes (i).vx := 0
    nodes (i).vy := 0
end for

var F : real
var mx, my, md, mxl, myl : int
var holding : int := -1

var connected : array 1 .. N, 1 .. N of boolean
for i : 1 .. N
    for j : 1 .. N
        %connected (i, j) := i ~= j & (i = 1| j = 1| abs (i - j) = 1| abs (j - i) = 1| (i = 2 & j = N)| (i = N & j = 2)) %connected in a loop and to a center node
        connected (i, j) := i ~= j %everyone connected to each other
    end for
end for

function whatAngle (dx, dy : real) : real
    var ratio, angle : real
    if abs (dx) > 0.0000001 then
        ratio := dy / dx
    else
        ratio := dy / 0.000001
    end if
    angle := arctand (abs (ratio))
    if dx < 0 then
        angle := 180 - angle
    end if
    if dy < 0 then
        angle := 360 - angle
    end if
    result angle
end whatAngle

loop
    mousewhere (mx, my, md)

    for i : 1 .. N
        nodes (i).vx := nodes (i).vx * decay + wind
        nodes (i).vy := nodes (i).vy * decay + g
        for j : 1 .. N
            if connected (i, j) then
                F := -k * (Math.Distance (nodes (j).x, nodes (j).y, nodes (i).x, nodes (i).y) - d)
                nodes (i).vx += cosd (whatAngle (nodes (i).x - nodes (j).x, nodes (i).y - nodes (j).y)) * F
                nodes (i).vy += sind (whatAngle (nodes (i).x - nodes (j).x, nodes (i).y - nodes (j).y)) * F
            end if
        end for
    end for

    for i : 1 .. N
        for j : 1 .. N
            if connected (i, j) then
                drawline (nodes (i).x div 1, nodes (i).y div 1, nodes (j).x div 1, nodes (j).y div 1, grey)
            end if
        end for
    end for
    for i : 1 .. N
        if i ~= holding then
            nodes (i).x += nodes (i).vx
            nodes (i).y += nodes (i).vy
            if (nodes (i).x < radius| nodes (i).x > maxx - radius) then
                nodes (i).vx *= -1
            end if
            if (nodes (i).y < radius| nodes (i).y > maxy - radius) then
                nodes (i).vy *= -1
            end if
            nodes (i).x := min (max (radius, nodes (i).x), maxx - radius)
            nodes (i).y := min (max (radius, nodes (i).y), maxy - radius)
            if Math.Distance (mx, my, nodes (i).x, nodes (i).y)  0 then
        if holding = -1 then
            for i : 1 .. N
                if Math.Distance (mx, my, nodes (i).x, nodes (i).y) 