Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Resolution of simulation
- local NUM_POINTS = ScrW()/2
- -- Width of simulation
- local WIDTH = ScrW()
- -- Spring constant for forces applied by adjacent points
- local SPRING_CONSTANT = 0.04
- -- Sprint constant for force applied to baseline
- local SPRING_CONSTANT_BASELINE = 0.001
- -- Vertical draw offset of simulation
- local Y_OFFSET = ScrH()-256
- -- Damping to apply to speed changes
- local DAMPING = 0.959
- -- Number of iterations of point-influences-point to do on wave per step
- -- (this makes the waves animate faster)
- local ITERATIONS = 3
- -- Make points to go on the wave
- function makeWavePoints(numPoints)
- local t = {}
- for n = 1,numPoints do
- -- This represents a point on the wave
- local newPoint = {
- x = n / numPoints * WIDTH,
- y = Y_OFFSET,
- spd = {y=0}, -- speed with vertical component zero
- mass = 1
- }
- t[n] = newPoint
- end
- return t
- end
- local wavePoints = makeWavePoints(NUM_POINTS)
- -- A phase difference to apply to each sine
- local offset = 0
- local NUM_BACKGROUND_WAVES = 3
- local BACKGROUND_WAVE_MAX_HEIGHT = 16
- local BACKGROUND_WAVE_COMPRESSION = 1/10
- -- Amounts by which a particular sine is offset
- local sineOffsets = {}
- -- Amounts by which a particular sine is amplified
- local sineAmplitudes = {}
- -- Amounts by which a particular sine is stretched
- local sineStretches = {}
- -- Amounts by which a particular sine's offset is multiplied
- local offsetStretches = {}
- -- Set each sine's values to a reasonable random value
- for i=1,NUM_BACKGROUND_WAVES do
- table.insert(sineOffsets, -1 + 2*math.random())
- table.insert(sineAmplitudes, math.random()*BACKGROUND_WAVE_MAX_HEIGHT)
- table.insert(sineStretches, math.random()*BACKGROUND_WAVE_COMPRESSION)
- table.insert(offsetStretches, math.random()*BACKGROUND_WAVE_COMPRESSION)
- end
- -- This function sums together the sines generated above,
- -- given an input value x
- function overlapSines(x)
- local result = 0
- for i=1,NUM_BACKGROUND_WAVES do
- result = result
- + sineOffsets[i]
- + sineAmplitudes[i] * math.sin(
- x * sineStretches[i] + offset * offsetStretches[i])
- end
- return result
- end
- -- Update the positions of each wave point
- function updateWavePoints(points)
- for i=1,ITERATIONS do
- for n,p in ipairs(points) do
- -- force to apply to this point
- local force = 0
- -- forces caused by the point immediately to the left or the right
- local forceFromLeft, forceFromRight
- if n == 1 then -- wrap to left-to-right
- local dy = points[# points].y - p.y
- forceFromLeft = SPRING_CONSTANT * dy
- else -- normally
- local dy = points[n-1].y - p.y
- forceFromLeft = SPRING_CONSTANT * dy
- end
- if n == # points then -- wrap to right-to-left
- local dy = points[1].y - p.y
- forceFromRight = SPRING_CONSTANT * dy
- else -- normally
- local dy = points[n+1].y - p.y
- forceFromRight = SPRING_CONSTANT * dy
- end
- -- Also apply force toward the baseline
- local dy = Y_OFFSET - p.y
- forceToBaseline = SPRING_CONSTANT_BASELINE * dy
- -- Sum up forces
- force = force + forceFromLeft
- force = force + forceFromRight
- force = force + forceToBaseline
- -- Calculate acceleration
- local acceleration = force / p.mass
- -- Apply acceleration (with damping)
- p.spd.y = DAMPING * p.spd.y + acceleration
- -- Apply speed
- p.y = p.y + p.spd.y
- end
- end
- end
- -- Callback when updating
- hook.Add("HUDPaint","waves",function()
- offset = offset + 1
- -- On click: Pick nearest point to mouse position
- if input.IsMouseDown(MOUSE_LEFT) and input.IsKeyDown(KEY_C) then
- local mouseX, mouseY = gui.MouseX( ),gui.MouseY( )/10
- local closestPoint = nil
- local closestDistance = nil
- for _,p in ipairs(wavePoints) do
- local distance = math.abs(mouseX-p.x)
- if closestDistance == nil then
- closestPoint = p
- closestDistance = distance
- else
- if distance <= closestDistance then
- closestPoint = p
- closestDistance = distance
- end
- end
- end
- closestPoint.y = gui.MouseY( )
- end
- -- Update positions of points
- updateWavePoints(wavePoints)
- for n,p in ipairs(wavePoints) do
- -- Draw lines between circles
- if n == 1 then
- else
- local leftPoint = wavePoints[n-1]
- surface.SetDrawColor(85,85,255,155)
- surface.DrawRect(leftPoint.x, leftPoint.y + overlapSines(leftPoint.x), 2, 1024+overlapSines(p.x))
- end
- end
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement