Question

I've been trying to create a force-directed graphing algorithm with RBX::Lua. So far, everything seems to be working absolutely fine mathematically, but there are a couple of things that make absolutely no sense at all.

My problem is, the nodes experience an unexpected attraction to one another, whether connected or not. What the program does is, all of the unconnected nodes repel each other like a magnet, and all of the connected nodes attract each other like a spring.

I don't see anything in my code that could be causing this.

-- Creating an icon to represent each node
local n = Instance.new("Part", Instance.new("Humanoid", Instance.new("Model")).Parent)
n.Name = "Head"
local tor = Instance.new("Part", n.Parent)
tor.Name = "Torso"
tor.Anchored = true
tor.FormFactor = "Custom"
tor.Transparency = 1
local h = n.Parent.Humanoid
h.Health = 0
h.MaxHealth = 0
h.Parent.Name = "Node"
n.FormFactor = "Symmetric"
n.Shape = "Ball"
n.TopSurface, n.BottomSurface = "Smooth", "Smooth"
n.Size = Vector3.new(2,2,2)
n.BrickColor = BrickColor.new("Institutional white")
n.Anchored = true
Instance.new("Vector3Value", n).Name = "velocity"

-- List of connections and nodes
local t = {
    ["Metals"]={"Gold", "Silver", "Steel", "Brass", "Mercury"},
    ["Alloys"]={"Steel", "Brass"},
    ["Noble Gasses"]={"Helium", "Argon", "Krypton", "Xenon"},
    ["Water"]={"Hydrogen", "Oxygen"},
    ["Liquids"]={"Water", "Mercury"},
    ["Alone"]={}
}
--[[ -- Separate list for testing, commented out
local t = {
    ["A"]={"B"},
    ["B"]={"C"},
    ["C"]={"D"},
    ["D"]={"E"},
    ["E"]={"F"}
}]]

-- Add all of the nodes to the workspace, position them randomly
for _, v in pairs(t) do
    local p1 = workspace:findFirstChild(_) or n.Parent:clone()
    p1.Name = _
    p1.Parent = workspace
    p1.Head.CFrame = CFrame.new(Vector3.new(math.random(-100000,100000)/1000,0,math.random(-100000,100000)/1000))
    for a, b in ipairs(v) do
        if v ~= b then
            local p2 = workspace:findFirstChild(b) or n.Parent:clone()
            p2.Name = b
            p2.Parent = workspace
            p2.Head.CFrame = CFrame.new(Vector3.new(math.random(-100000,100000)/1000,0,math.random(-100000,100000)/1000))
            local at = p1:findFirstChild(b) or Instance.new("ObjectValue", p1)
            at.Name = b
            local at2 = at:clone()
            at2.Parent = p2
            at2.Name = _
            local lasso = Instance.new("SelectionPartLasso", p2.Head)
            lasso.Name = "Link"
            lasso.Humanoid = p2.Humanoid
            lasso.Part = p1.Head
            lasso.Color = BrickColor.new("Institutional white")
        end
    end
end

local parts = {} -- List of all of the nodes themselves
-- Add all of the nodes to the list
for _, v in ipairs(workspace:GetChildren()) do
    if v.ClassName == "Model" then
        table.insert(parts, v.Head)
    end
end

while wait() do -- Repeat forever waiting one frame between loops
    for _, v in ipairs(parts) do
        for a, b in ipairs(parts) do
            if v ~= b then
                local dif = b.Position-v.Position
                local force = 0
                if b.Parent:findFirstChild(v.Name) then -- if b is conneted to v
                    force = (dif.magnitude-30)/100
                else
                    force = force - 1/dif.magnitude^2
                end
                local add = dif/dif.magnitude*force
                add = add - v.Position/v.Position.magnitude/100
                v.velocity.Value = v.velocity.Value + add
            end
        end
        v.CFrame = v.CFrame + v.velocity.Value -- Postion the node
        v.velocity.Value = v.velocity.Value*.2 -- Damping
        v.CFrame = v.CFrame-v.CFrame.p*Vector3.new(0,1,0) -- Force 2D (optional)
        v.Parent.Torso.CFrame = v.CFrame -- To display links connecting nodes
    end
end
Was it helpful?

Solution

I found the problem. "b.Parent:findFirstChild(v.Name)" should have been "b.Parent:findFirstChild(v.Parent.Name)," otherwise it will just return true every time. This is just because of how I have the display of the nodes set up.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top