diff options
| author | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-13 02:49:48 -0500 |
|---|---|---|
| committer | Nic Gaffney <gaffney_nic@protonmail.com> | 2025-10-13 02:49:48 -0500 |
| commit | 167fdaf8b41d19f119df8484f004d968e9fc68fd (patch) | |
| tree | bc17f87c2c14638e3ac004847c9d26e20ffc418a /src/particle.zig | |
| parent | 2f1f9beb60309df8d2de011b19402a79ef8101fa (diff) | |
| download | particle-sim-167fdaf8b41d19f119df8484f004d968e9fc68fd.tar.gz | |
Update to zig 0.15.1 complete, along with further optimization
Diffstat (limited to 'src/particle.zig')
| -rw-r--r-- | src/particle.zig | 34 |
1 files changed, 16 insertions, 18 deletions
diff --git a/src/particle.zig b/src/particle.zig index d33e7ce..14748dc 100644 --- a/src/particle.zig +++ b/src/particle.zig @@ -9,9 +9,10 @@ pub const particle = struct { xvel: f32, yvel: f32, }; -/// Initialize a MultiArrayList of size amnt with particles created by createParticle -pub fn initParticles(allocator: std.mem.Allocator, amnt: u32) !std.ArrayList(particle) { - var particles = std.ArrayList(particle).init(allocator); + +/// Initialize an array_list.Managed of size amnt with particles created by createParticle +pub fn initParticles(allocator: std.mem.Allocator, amnt: u32) !std.array_list.Managed(particle) { + var particles = std.array_list.Managed(particle).init(allocator); try particles.ensureTotalCapacity(cfg.particleMax); for (0..amnt) |_| try particles.append(createParticle()); @@ -21,38 +22,38 @@ pub fn initParticles(allocator: std.mem.Allocator, amnt: u32) !std.ArrayList(par /// Applies forces from the ruleset to each particle pub fn updateVelocities( - particles: std.ArrayList(particle), + particles: std.array_list.Managed(particle), qtree: quad.Quad(particle, cfg.quadSplitLimit), threadidx: u64, + particlesInRange: *std.ArrayList(particle), ) !void { const rules = cfg.rules; - var particlesInRange = std.ArrayList(particle).init(qtree.allocator); - defer particlesInRange.deinit(); var i = threadidx; while (i < particles.items.len) : (i += cfg.numThreads) { var p: *particle = &(particles.items[i]); defer particlesInRange.clearRetainingCapacity(); const radius = cfg.radius[p.colorId]; - try qtree.radiusSearchWrapping(p.pos, @intCast(radius), &particlesInRange, rl.getScreenWidth(), rl.getScreenHeight()); + try qtree.radiusSearchWrapping(p.pos, @intCast(radius), particlesInRange, rl.getScreenWidth(), rl.getScreenHeight()); var forceX: f32 = 0.0; var forceY: f32 = 0.0; const floatRadius = @as(f32, @floatFromInt(radius)); const floattMinDistance = @as(f32, @floatFromInt(cfg.minDistance)); for (particlesInRange.items) |p2| { if (p.pos.x == p2.pos.x and p.pos.y == p2.pos.y) continue; + // distance calculations const distance_x: f32 = @floatFromInt(p.pos.x - p2.pos.x); const distance_y: f32 = @floatFromInt(p.pos.y - p2.pos.y); var distance = @sqrt(distance_x * distance_x + distance_y * distance_y); if (distance == 0) distance = 0.01; + // force calculations const f = -force(distance, floatRadius, rules[p.colorId][p2.colorId]); forceX += (distance_x / distance) * f; forceY += (distance_y / distance) * f; } + // update velocity forceX = forceX * floattMinDistance / floatRadius; - // forceX = std.math.clamp(forceX, -10.0, 10.0); forceY = forceY * floattMinDistance / floatRadius; - // forceY = std.math.clamp(forceY, -10.0, 10.0); - p.xvel *= cfg.friction ; + p.xvel *= cfg.friction; p.xvel += forceX; p.yvel *= cfg.friction; p.yvel += forceY; @@ -60,18 +61,15 @@ pub fn updateVelocities( } /// Applies the particles velocity and updates position -pub fn updatePosition(particles: *std.ArrayList(particle)) void { +pub fn updatePosition(particles: *std.array_list.Managed(particle)) void { for (particles.items) |*p| { - const maxVel: f32 = 4096.0; - const posYplusVel: f32 = @as(f32, @floatFromInt(p.pos.y)) + std.math.clamp(p.yvel, -maxVel, maxVel); - const posXplusVel: f32 = @as(f32, @floatFromInt(p.pos.x)) + std.math.clamp(p.xvel, -maxVel, maxVel); - p.pos.y = @mod(@as(i32, @intFromFloat(posYplusVel)), rl.getScreenHeight()); - p.pos.x = @mod(@as(i32, @intFromFloat(posXplusVel)), rl.getScreenWidth()); + p.pos.y = @mod(@as(i32, @intFromFloat(@round(@as(f32, @floatFromInt(p.pos.y)) + (@as(f32, @floatFromInt(cfg.speed[p.colorId])) / 1000.0) * p.yvel))), rl.getScreenHeight()); + p.pos.x = @mod(@as(i32, @intFromFloat(@round(@as(f32, @floatFromInt(p.pos.x)) + (@as(f32, @floatFromInt(cfg.speed[p.colorId])) / 1000.0) * p.xvel))), rl.getScreenWidth()); } } /// Draw the particles onto the screen using raylib -pub fn draw(particles: std.ArrayList(particle)) void { +pub fn draw(particles: std.array_list.Managed(particle)) void { for (particles.items) |p| rl.drawRectangle(p.pos.x, p.pos.y, 5, 5, cfg.colors[p.colorId]); } @@ -88,7 +86,7 @@ fn force(distance: f32, radius: f32, attraction: f32) f32 { pub fn createParticle() particle { const seed = @as(u64, @truncate(@as(u128, @bitCast(std.time.nanoTimestamp())))); - var prng = std.rand.DefaultPrng.init(seed); + var prng = std.Random.DefaultPrng.init(seed); const x = prng.random().uintLessThan(u32, @intCast(rl.getScreenWidth())); const y = prng.random().uintLessThan(u32, @intCast(rl.getScreenHeight())); const color = prng.random().uintLessThan(u32, cfg.colorAmnt); |
