aboutsummaryrefslogtreecommitdiff
path: root/src/main.zig
diff options
context:
space:
mode:
authorNic Gaffney <gaffney_nic@protonmail.com>2024-06-12 17:21:10 -0500
committerNic Gaffney <gaffney_nic@protonmail.com>2024-06-12 17:21:10 -0500
commit6084001df845815efd9c0eb712acf4fd9311ce36 (patch)
tree09a22b240b8d1739064d7d165730e3aeeec27cf2 /src/main.zig
parentc7e504f40cca3ceee1734e6d0d9447c92d17b6b1 (diff)
downloadparticle-sim-6084001df845815efd9c0eb712acf4fd9311ce36.tar.gz
Split up files
Diffstat (limited to 'src/main.zig')
-rw-r--r--src/main.zig160
1 files changed, 9 insertions, 151 deletions
diff --git a/src/main.zig b/src/main.zig
index ec8e87c..47906e2 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -1,37 +1,13 @@
const std = @import("std");
const rl = @import("raylib");
-
-const particle = struct {
- colorId: u32,
- attrs: particleAttrs,
- x: i32,
- y: i32,
- xvel: f32,
- yvel: f32,
-};
-
-const particleAttrs = struct {};
-const screenWidth = 2560;
-const screenHeight = 1440;
-const particleMax = 5000;
-const radius = 100.0;
-const minDistance = 20.0;
-const colors = [_]rl.Color{
- rl.Color.red,
- rl.Color.green,
- rl.Color.blue,
- rl.Color.yellow,
- rl.Color.magenta,
- rl.Color.brown,
- rl.Color.orange,
-};
-const colorAmnt = colors.len;
+const part = @import("particle.zig");
+const cfg = @import("config.zig");
pub fn main() !void {
- const rules = ruleMatrix(colors.len);
- printRules(rules);
+ const rules = part.ruleMatrix();
+ part.printRules(rules);
- rl.initWindow(screenWidth, screenHeight, "Particle Simulator");
+ rl.initWindow(cfg.screenWidth, cfg.screenHeight, "Particle Simulator");
defer rl.closeWindow();
rl.setTargetFPS(60);
@@ -39,7 +15,7 @@ pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer _ = gpa.deinit();
- var particles = try initParticles(gpa.allocator(), 3000);
+ var particles = try part.initParticles(gpa.allocator(), cfg.initialParticles);
defer particles.deinit(gpa.allocator());
while (!rl.windowShouldClose()) {
@@ -48,128 +24,10 @@ pub fn main() !void {
defer rl.endDrawing();
- updateVelocities(particles, rules);
-
- for (particles.items(.y), particles.items(.yvel)) |*y, yvel|
- y.* = @mod(@as(i32, @intFromFloat(@round((@as(f32, @floatFromInt(y.*)) + yvel)))), screenHeight);
-
- for (particles.items(.x), particles.items(.xvel)) |*x, xvel|
- x.* = @mod(@as(i32, @intFromFloat(@round((@as(f32, @floatFromInt(x.*)) + xvel)))), screenWidth);
-
- for (particles.items(.y), particles.items(.x), particles.items(.colorId)) |*y, *x, colorId|
- rl.drawRectangle(x.*, y.*, 5, 5, colors[colorId]);
+ part.updateVelocities(particles, rules);
+ part.updatePosition(particles);
+ part.draw(particles);
rl.clearBackground(rl.Color.black);
}
}
-
-fn colorToString(c: usize) []const u8 {
- return switch (c) {
- 0 => "R",
- 1 => "G",
- 2 => "Bl",
- 3 => "Y",
- 4 => "M",
- 5 => "Br",
- 6 => "O",
- else => " ",
- };
-}
-
-fn printRules(rules: [colorAmnt][colorAmnt]f32) void {
- std.debug.print("\n|{s:^6}", .{"Rules"});
- for (0..colors.len) |c|
- std.debug.print("| {s:^4} ", .{colorToString(c)});
-
- std.debug.print("|\n", .{});
- for (rules, 0..) |row, i| {
- std.debug.print("| {s:^4} ", .{colorToString(i)});
- for (row) |col|
- std.debug.print("| {d:^4.1} ", .{col});
-
- std.debug.print("|\n", .{});
- }
-}
-
-fn force(distance: f32, attraction: f32) f32 {
- const beta = minDistance / radius;
- const r: f32 = distance / radius;
- if (r < beta)
- return -(r / beta - 1.0);
- if (beta <= r and r < 1)
- return attraction * (1 - @abs(2.0 * r - 1.0 - beta) / (1.0 - beta));
- return 0;
-}
-
-fn updateVelocities(particles: std.MultiArrayList(particle), rules: [colorAmnt][colorAmnt]f32) void {
- const colorList = particles.items(.colorId);
- var xvel = particles.items(.xvel);
- var yvel = particles.items(.yvel);
- for (particles.items(.x), particles.items(.y), 0..) |x, y, i| {
- var forceX: f32 = 0.0;
- var forceY: f32 = 0.0;
-
- for (particles.items(.x), particles.items(.y), 0..) |x2, y2, j| {
- if (i == j) continue;
- const rx: f32 = @floatFromInt(x - x2);
- const ry: f32 = @floatFromInt(y - y2);
- var r = @sqrt(rx * rx + ry * ry);
- if (r == 0) {
- r = 0.0001;
- }
- if (r > 0 and r < radius) {
- const f = force(r, rules[colorList[i]][colorList[j]]);
- forceX = forceX + rx / r * f;
- forceY = forceY + ry / r * f;
- }
- }
-
- forceX = forceX * minDistance / radius;
- forceY = forceY * minDistance / radius;
-
- xvel[i] = xvel[i] * 0.95 + forceX;
- yvel[i] = yvel[i] * 0.95 + forceY;
- }
-}
-
-/// Generates a particle with a random Color and Location
-pub fn createParticle(attrs: particleAttrs) particle {
- const seed = @as(u64, @truncate(@as(u128, @bitCast(std.time.nanoTimestamp()))));
- var prng = std.rand.DefaultPrng.init(seed);
- const x = prng.random().uintLessThan(u32, screenWidth);
- const y = prng.random().uintLessThan(u32, screenHeight);
- const color = prng.random().uintLessThan(u32, colorAmnt);
- return particle{
- .colorId = color,
- .attrs = attrs,
- .x = @intCast(x),
- .y = @intCast(y),
- .xvel = 0,
- .yvel = 0,
- };
-}
-
-fn ruleMatrix(comptime size: u32) [size][size]f32 {
- const seed = @as(u64, @truncate(@as(u128, @bitCast(std.time.nanoTimestamp()))));
- var prng = std.rand.DefaultPrng.init(seed);
- var rules: [size][size]f32 = undefined;
- for (0..size) |i| {
- for (0..size) |j| {
- var val = prng.random().float(f32);
- const isNeg = prng.random().uintAtMost(u8, 1);
- if (isNeg == 1) val = 0 - val;
- rules[i][j] = val;
- }
- }
- return rules;
-}
-
-/// Initialize a MultiArrayList of size amnt with particles created by createParticle
-pub fn initParticles(allocator: std.mem.Allocator, amnt: u32) !std.MultiArrayList(particle) {
- var particles = std.MultiArrayList(particle){};
- try particles.setCapacity(allocator, 10000);
- for (0..amnt) |_| {
- try particles.append(allocator, createParticle(.{}));
- }
- return particles;
-}