Created
May 18, 2025 06:50
-
-
Save Hammer2900/281c61c1636e5a37119b1190da14c6b7 to your computer and use it in GitHub Desktop.
interactive n-body particle simulation in lobster
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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