A Crappy Plasma Globe

Here’s a little crappy plasma globe demo I made today. It was inspired by some code I found for implementing a simple electricity effect at http://krazydad.com/bestiary/bestiary_lightning.html . If you change the display mode to STANDARD you can tweak all of the various parameters for it. With a some effort this could be made a lot less crappy, but since I’m just playing around I don’t really care to do anymore to it.

function setup()
    displayMode(FULLSCREEN)
    supportedOrientations(LANDSCAPE_ANY)
    
    iparameter("minBolts", 1, 50, 5)
    iparameter("maxBolts", 1, 50, 10)
    iparameter("minLineWidth", 1, 20, 3)
    iparameter("maxLineWidth", 1, 20, 5)
    iparameter("minDetail", 1, 30, 5)
    iparameter("maxDetail", 1, 30, 20)
    iparameter("minDisplacement", 1, 1000, 100)
    iparameter("maxDisplacement", 1, 1000, 200)

    touches = {}
    
    center = vec2(WIDTH*0.5, HEIGHT*0.5)
    diameter = math.min(WIDTH, HEIGHT)
    radius = diameter * 0.5
end

function touched(touch)
    if touch.state == BEGAN or touch.state == MOVING then
        local tp = vec2(touch.x, touch.y)
        if center:distSqr(tp) <= radius*radius then
            touches[touch.id] = tp
        else
            local v = (tp - center):normalize() * (radius-8)
            touches[touch.id] = center + v
        end
    elseif touch.state == ENDED then
        touches[touch.id] = nil
    end
end

-- ported from code at http://krazydad.com/bestiary/bestiary_lightning.html
function drawLightning(x1, y1, x2, y2, displace, detail)
    if displace < detail then
        line(x1, y1, x2, y2)
    else
        local midx = (x2+x1) * 0.5
        local midy = (y2+y1) * 0.5
        midx = midx + (math.random() - 0.5) * displace
        midy = midy + (math.random() - 0.5) * displace
        drawLightning(x1, y1, midx, midy, displace * 0.5, detail)
        drawLightning(x2, y2, midx, midy, displace * 0.5, detail)
    end
end

function draw()
    background(0)
    
    -- swap max and mins if necessary
    local minB = math.min(minBolts, maxBolts)
    local maxB = math.max(minBolts, maxBolts)
    local minW = math.min(minLineWidth, maxLineWidth)
    local maxW = math.max(minLineWidth, maxLineWidth)    
    local minDt = math.min(minDetail, maxDetail)
    local maxDt = math.max(minDetail, maxDetail)    
    local minDp = math.min(minDisplacement, maxDisplacement)
    local maxDp = math.max(minDisplacement, maxDisplacement)
    
    -- count touch points
    local numTouchBolts = 0    
    for k,v in pairs(touches) do numTouchBolts = numTouchBolts + 1 end
    
    -- draw thin bolts
    lineCapMode(PROJECT)
    stroke(64, 64, 255)
    local numBolts = math.random(minB, maxB)
    local mb = math.random(0, 1)
    numBolts = math.max(mb, numBolts - numTouchBolts*4)
    for i = 1, numBolts do
        local detail = math.random(minDt, maxDt)
        local displace = math.random(minDp, maxDp)
        local angle = math.rad(math.random(0, 360))
        local rv = vec2(0, 1):rotate(angle) * radius
        local p = center + rv
        strokeWidth(math.random(minW, maxW))
        drawLightning(center.x, center.y, p.x, p.y, displace, detail)
    end
    
    -- draw thicker bolts to touch points
    lineCapMode(ROUND)    
    strokeWidth(maxW * 3)
    stroke(256, 0, 128)
    for k,v in pairs(touches) do
        local detail = math.random(minDt, maxDt)
        local displace = math.random(minDp, maxDp) * 0.5
        drawLightning(center.x, center.y, v.x, v.y, displace, detail)
    end        
    
    -- draw the ball edge
    strokeWidth(5)
    stroke(128)
    fill(0, 0, 0, 0)    
    ellipse(WIDTH/2, HEIGHT/2, diameter) 
    
    -- draw the ball center
    noStroke()
    fill(192, 0, 128)
    ellipse(WIDTH/2, HEIGHT/2, 50)
end

Very good, @toadkick.

Nice! Not crappy. Love it!

Thanks! :slight_smile: