Skip to content

Instantly share code, notes, and snippets.

@Hammer2900
Created May 18, 2025 06:50
Show Gist options
  • Save Hammer2900/281c61c1636e5a37119b1190da14c6b7 to your computer and use it in GitHub Desktop.
Save Hammer2900/281c61c1636e5a37119b1190da14c6b7 to your computer and use it in GitHub Desktop.
interactive n-body particle simulation in lobster
import std
import vec
import color
import gl
// --- Global Particle Data (Structure of Arrays - SoA) ---
var masses:[float] = []
var positions_x:[float] = []
var positions_y:[float] = []
var velocities_x:[float] = []
var velocities_y:[float] = []
def add_new_particle(mouse_x:float, mouse_y:float):
masses.push(rnd_float() * (0.03 - 0.003) + 0.003)
positions_x.push(mouse_x)
positions_y.push(mouse_y)
velocities_x.push(0.0)
velocities_y.push(0.0)
def main():
let screen_width = 800.0
let screen_height = 600.0
fatal(gl.window("Lobster Particle Simulation", int(screen_width), int(screen_height)))
gl.set_target_delta_time(1.0 / 60.0)
while gl.frame() and gl.button("escape") != 1:
let mouse_screen_pos = gl.mouse_pos(0) // Get mouse position (int2)
let mouse_pos = float(mouse_screen_pos) // Convert to float2
if gl.button("mouse1") >= 1:
add_new_particle(mouse_pos.x, mouse_pos.y)
// Update particle physics (N-body simulation style)
for(masses.length) particle_a_idx:
var acceleration_x = 0.0
var acceleration_y = 0.0
for(masses.length) particle_b_idx:
if particle_a_idx != particle_b_idx:
let dist_x = positions_x[particle_b_idx] - positions_x[particle_a_idx]
let dist_y = positions_y[particle_b_idx] - positions_y[particle_a_idx]
var distance_sq = dist_x * dist_x + dist_y * dist_y
if distance_sq < 1.0: // Избегаем деления на ноль и слишком больших сил
distance_sq = 1.0
let distance = sqrt(distance_sq)
let force_magnitude = (distance - 320.0) * masses[particle_b_idx] / distance
acceleration_x += force_magnitude * dist_x
acceleration_y += force_magnitude * dist_y
velocities_x[particle_a_idx] = velocities_x[particle_a_idx] * 0.99 + acceleration_x * masses[particle_a_idx]
velocities_y[particle_a_idx] = velocities_y[particle_a_idx] * 0.99 + acceleration_y * masses[particle_a_idx]
for(masses.length) particle_idx:
positions_x[particle_idx] += velocities_x[particle_idx]
positions_y[particle_idx] += velocities_y[particle_idx]
gl.clear(float4 { 32.0/255.0, 32.0/255.0, 32.0/255.0, 1.0 })
let particle_color = float4 { 64.0/255.0, 255.0/255.0, 255.0/255.0, 192.0/255.0 } // Cyan with alpha
gl.color(particle_color)
for(masses.length) particle_idx:
let radius = masses[particle_idx] * 1000.0 // Radius proportional to mass
let pos_x = positions_x[particle_idx]
let pos_y = positions_y[particle_idx]
gl.translate(float2 { pos_x, pos_y }):
gl.circle(radius, 12)
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment