commit bd4c39654ce3dd13ad8e5a2202470f79fd89575e parent 68ab63038f2a64ae671e7915e91bb8355e5167e4 Author: Andrew Laack <andrew@laack.co> Date: Tue, 15 Sep 2026 23:53:01 -0500 Moving to dedicated repo, keeping history Diffstat:
28 files changed, 23 insertions(+), 797 deletions(-)
diff --git a/background/Makefile b/Makefile diff --git a/README b/README @@ -1,3 +1,23 @@ -Visualizations -============== -These are an assortment of programmatic visualizations I've created. +abg - animated background +========================= + + +dependencies +============ +X11, raylib, g++ + + +usage +===== + Usage: abg [--help] [--version] [--vertices VAR] [--edges VAR] + + Optional arguments: + -h, --help shows help message and exits + -v, --version prints version information and exits + --vertices number of vertices in the graph [nargs=0..1] [default: 200] + -e, --edges number of edges in the graph [nargs=0..1] [default: 1000] + +examples +======== + abg --edges 50 --vertices 10 + abg --edges 1500 --vertices 1000 diff --git a/background/README b/background/README @@ -1,23 +0,0 @@ -abg - animated background -========================= - - -dependencies -============ -X11, raylib, g++ - - -usage -===== - Usage: abg [--help] [--version] [--vertices VAR] [--edges VAR] - - Optional arguments: - -h, --help shows help message and exits - -v, --version prints version information and exits - --vertices number of vertices in the graph [nargs=0..1] [default: 200] - -e, --edges number of edges in the graph [nargs=0..1] [default: 1000] - -examples -======== - abg --edges 50 --vertices 10 - abg --edges 1500 --vertices 1000 diff --git a/graph/bfs.py b/graph/bfs.py @@ -1,110 +0,0 @@ -import pygame -import time -import heapq -import random -import math - -pygame.init() - -display = pygame.display.set_mode((5120,1440)) - -VERTICES = 1000 -EDGES = 1000 - -white = (255, 255, 255) -red = (255, 0, 0) -black = (0, 0, 0) -grey = (100,100,100) -light_grey = (0,0,0) - - -class Vertex(): - def __init__(self, x, y): - self.x = x - self.y = y - self.visited = False - - def draw_vertex(self,display): - if self.visited: - pygame.draw.circle(display, white, (self.x,self.y), 5) - else: - pygame.draw.circle(display, grey, (self.x,self.y), 5) - -class Edge(): - def __init__(self, v1, v2): - self.v1 = v1 - self.v2 = v2 - self.dist = math.sqrt(((v1.x - v2.x) ** 2) + ((v1.y - v2.y) ** 2)) - - def draw_edge(self,display, c): - pygame.draw.line(display, c, (self.v1.x,self.v1.y), (self.v2.x,self.v2.y), 1) - - def __lt__(self,otr): - return self.dist < otr.dist - - -graph = {} -for i in range(0,VERTICES): - x = random.random() * 5120 - y = random.random() * 1440 - graph[Vertex(x,y)] = [] - - -edge_list = [] -for i in range(0,EDGES): - k1 = None - k2 = None - while k1 == k2: - k1 = random.choice(list(graph.keys())) - k2 = random.choice(list(graph.keys())) - - edge = Edge(k1,k2) - graph[k1].append(edge) - graph[k2].append(edge) - edge_list.append(edge) - -done = False - - - -start_node = list(graph.keys())[0] -start_node.visited = True - -to_visit = [] -next_visit = [start_node] - -visited_edges = [] -already_seen = set() - - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - display.fill(black) - for vertex in graph: - vertex.draw_vertex(display) - for edge in edge_list: - edge.draw_edge(display, light_grey) - for edge in visited_edges: - edge.draw_edge(display, white) - - if done: - pygame.display.update() - pygame.image.save(display, "out.jpg") - break - - to_visit = next_visit - next_visit = [] - for next_node in to_visit: - next_node.visited = True - for edge in graph[next_node]: - visited_edges.append(edge) - if not edge.v2 in already_seen: - next_visit.append(edge.v2) - already_seen.add(edge.v2) - - time.sleep(1) - pygame.display.update() diff --git a/graph/mc_pi.py b/graph/mc_pi.py @@ -1,71 +0,0 @@ -import pygame -import time -import math -import random - -pygame.init() - -WIDTH=500 -HEIGHT=WIDTH - -display = pygame.display.set_mode((WIDTH,HEIGHT)) - -DOTS = 1000 -DOT_SIZE = 1 - -white = (255, 255, 255) -red = (255, 0, 0) -black = (0, 0, 0) -grey = (100,100,100) -light_grey = (50,50,50) - - -def distance(x_1,y_1,x_2,y_2): - return math.sqrt(((x_1 - x_2) ** 2) + ((y_1 - y_2) ** 2)) - -positions = [] -distances = [] - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - display.fill(black) - - pygame.draw.circle(display, white, (int(WIDTH/2), int(HEIGHT/2)), WIDTH/2) - - out = 0 - inside = 0 - - for i in range(0,DOTS): - pos_x = random.random() * WIDTH - pos_y = random.random() * WIDTH - pos = (pos_x,pos_y) - - dist = distance(pos_x,pos_y,int(WIDTH/2), int(HEIGHT/2)) - - if dist > WIDTH/2: - out += 1 - else: - inside += 1 - positions.append((pos_x,pos_y)) - distances.append(dist) - - for idx in range(0,len(positions)): - pos = positions[idx] - if distances[idx] > WIDTH/2: - pygame.draw.circle(display, white, pos, DOT_SIZE) - else: - pygame.draw.circle(display, black, pos, DOT_SIZE) - - pygame.display.update() - - percent_in = inside / (inside + out) - area_in = percent_in * WIDTH*HEIGHT - pi = area_in / ((WIDTH/2) ** 2) - - print(pi) - - time.sleep(.1) diff --git a/graph/prim.py b/graph/prim.py @@ -1,121 +0,0 @@ -import pygame -import os -import time -import heapq -import random -import math - -os.environ["SDL_VIDEODRIVER"] = "dummy" - -pygame.init() - -display = pygame.display.set_mode((5120,1440)) - -VERTICES = 100 -EDGES = 1000 - -white = (255, 255, 255) -red = (255, 0, 0) -black = (0, 0, 0) -grey = (100,100,100) -light_grey = (50,50,50) - - -class Vertex(): - def __init__(self, x, y): - self.x = x - self.y = y - self.visited = False - - def draw_vertex(self,display): - if self.visited: - pygame.draw.circle(display, white, (self.x,self.y), 5) - else: - pygame.draw.circle(display, grey, (self.x,self.y), 5) - -class Edge(): - def __init__(self, v1, v2): - self.v1 = v1 - self.v2 = v2 - self.dist = math.sqrt(((v1.x - v2.x) ** 2) + ((v1.y - v2.y) ** 2)) - - def draw_edge(self,display, c): - pygame.draw.line(display, c, (self.v1.x,self.v1.y), (self.v2.x,self.v2.y), 1) - - def __lt__(self,otr): - return self.dist < otr.dist - - -while True: - graph = {} - - for i in range(0,VERTICES): - x = random.random() * 5120 - y = random.random() * 1440 - graph[Vertex(x,y)] = [] - - - edge_list = [] - for i in range(0,EDGES): - k1 = None - k2 = None - while k1 == k2: - k1 = random.choice(list(graph.keys())) - k2 = random.choice(list(graph.keys())) - - edge = Edge(k1,k2) - graph[k1].append(edge) - graph[k2].append(edge) - edge_list.append(edge) - - - edge_heap = [] - visited_vertices = set() - - mst = [] - - start = random.choice(list(graph.keys())) - start.visited = True - visited_vertices.add(start) - for edge in graph[start]: - heapq.heappush(edge_heap, edge) - - while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - display.fill(black) - for edge in edge_list: - edge.draw_edge(display, light_grey) - for edge in mst: - edge.draw_edge(display, white) - for vertex in graph: - vertex.draw_vertex(display) - - item = None - while edge_heap: - candidate = heapq.heappop(edge_heap) - if (candidate.v1 in visited_vertices) != (candidate.v2 in visited_vertices): - item = candidate - break - - if item is None: - pygame.display.update() - break - - new_vertex = item.v2 if item.v1 in visited_vertices else item.v1 - visited_vertices.add(new_vertex) - new_vertex.visited = True - mst.append(item) - for edge in graph[new_vertex]: - heapq.heappush(edge_heap, edge) - - dir_name = "/dev/shm/bg/" - if not os.path.exists(dir_name): - os.mkdir(dir_name) - pygame.image.save(display, dir_name + "out.png") - os.system("/usr/bin/feh --no-fehbg --bg-tile '/dev/shm/bg/out.png' ") - time.sleep(.1) - pygame.display.update() diff --git a/grid/game-of-life.py b/grid/game-of-life.py @@ -1,82 +0,0 @@ -import pygame -import random -import pygame.locals -import sys - - -grid_size = int(sys.argv[1]) -living = int(sys.argv[2]) - - -pygame.init() - -WIDTH = 1500 -HEIGHT = 1500 - -WHITE = (255,255,255) -BLACK = (0,0,0) - -DISPLAY = pygame.display.set_mode((WIDTH,HEIGHT), pygame.RESIZABLE) - - -def simulate(prior): - result = [row[:] for row in prior] - - count = 0 - - for y in range(len(prior)): - for x in range(len(prior[y])): - neighbors = 0 - for dx in range(-1,2): - for dy in range(-1,2): - if dx == 0 and dy == 0: - continue - if dx + x < 0 or dx + x >= len(prior[y]): - continue - if dy + y < 0 or dy + y >= len(prior): - continue - neighbors += prior[dy+y][dx+x] - is_alive = prior[y][x] - if neighbors == 3 or (is_alive and neighbors == 2): - result[y][x] = 1 - count += 1 - else: - # this is a copy of input... - result[y][x] = 0 - - return result - - -def drawGrid(g): - blockSize = int(WIDTH / len(g)) - for y in range(0, WIDTH, blockSize): - for x in range(0, HEIGHT, blockSize): - if g[int(y / blockSize)][int(x / blockSize)] == 1: - rect = pygame.Rect(x, y, blockSize, blockSize) - pygame.draw.rect(DISPLAY, WHITE, rect) - else: - rect = pygame.Rect(x, y, blockSize, blockSize) - pygame.draw.rect(DISPLAY, BLACK, rect) - - -grid = [[0] * grid_size for _ in range(grid_size)] - -def seed(grid): - for i in range(0,living): - rnd_y = random.randint(0,len(grid) - 1) - rnd_x = random.randint(0,len(grid[0]) - 1) - grid[rnd_y][rnd_x] = 1 - -seed(grid) - -while True: - for event in pygame.event.get(): - if event.type == pygame.locals.QUIT: - pygame.quit() - exit() - - grid = simulate(grid) - - DISPLAY.fill(BLACK) - drawGrid(grid) - pygame.display.update() diff --git a/grid/random-grid.py b/grid/random-grid.py @@ -1,63 +0,0 @@ -import pygame, sys -import random -from pygame.locals import * - -pygame.init() - -RED = (255,0,0) -BLACK = (0, 0, 0) -WHITE = (255, 255, 255) - -Y=5 -X=5 - -WIDTH = 500 -HEIGHT = 500 - -DISPLAY = pygame.display.set_mode((WIDTH, HEIGHT)) -pygame.display.set_caption('Hello World!') - - - -grid = [ - [0,0,0,0,0], - [0,1,1,0,0], - [0,1,1,0,0], - [0,0,0,1,0], - [1,0,0,0,0] -] - -def simulate(prior): - neighbors = prior.copy() - - for y in range(len(prior)): - for x in range(len(prior[y])): - neighbors[y][x] = random.randint(0,2) - - return neighbors - - -def drawGrid(): - blockSize = int(WIDTH / len(grid)) - for x in range(0, WIDTH, blockSize): - for y in range(0, HEIGHT, blockSize): - if grid[int(x / blockSize)][int(y / blockSize)] == 1: - rect = pygame.Rect(x, y, blockSize, blockSize) - pygame.draw.rect(DISPLAY, WHITE, rect) - else: - rect = pygame.Rect(x, y, blockSize, blockSize) - pygame.draw.rect(DISPLAY, WHITE, rect, 1) - - - -while True: - for event in pygame.event.get(): - if event.type == QUIT: - pygame.quit() - sys.exit() - - grid = simulate(grid) - DISPLAY.fill(BLACK) - drawGrid() - pygame.display.update() - diff --git a/background/headers/background.hpp b/headers/background.hpp diff --git a/background/headers/constants.hpp b/headers/constants.hpp diff --git a/background/headers/edge.hpp b/headers/edge.hpp diff --git a/background/headers/graph.hpp b/headers/graph.hpp diff --git a/background/headers/prim.hpp b/headers/prim.hpp diff --git a/background/headers/utils.hpp b/headers/utils.hpp diff --git a/background/headers/vertex.hpp b/headers/vertex.hpp diff --git a/movement/boids.py b/movement/boids.py @@ -1,140 +0,0 @@ -import pygame -import random -import time - -red = (255, 0, 0) -white = (255,255,255) - - -NUM_BOIDS = 300 - -class Boid: - - pos_x = 0 - pos_y = 0 - vel_x = 100 - vel_y = 100 - delta_y = 0 - delta_x = 0 - max_velocity = 100 - ACC = 1 - - NEARBY_DISTANCE = 40 - SEPERATION_DISTANCE = 10 - - def __init__(self): - self.pos_x = random.randint(0,500) - self.pos_y = random.randint(0,500) - self.last_time = time.time() - self.vel_x = random.randint(-100,100) - self.vel_y = random.randint(-100,100) - - def draw(self,display): - pygame.draw.circle(display, white, (self.pos_x, self.pos_y), 2) - - def distance(self,otr): - return ((self.pos_x - otr.pos_x) ** 2 + (self.pos_y - otr.pos_y) ** 2) ** .5 - - def move(self): - self.pos_x = self.pos_x + self.delta_x - self.pos_y = self.pos_y + self.delta_y - - def compute_move(self, flock): - - if self.pos_x > 500 and self.vel_x > 0: - self.vel_x *= -1 - - if self.pos_x < 0 and self.vel_x < 0: - self.vel_x *= -1 - - if self.pos_y > 500 and self.vel_y > 0: - self.vel_y *= -1 - - if self.pos_y < 0 and self.vel_y < 0: - self.vel_y *= -1 - - nearby_headings = [] - nearby_positions = [] - too_close = [] - - for i in range(0,len(flock)): - if flock[i] == self: - continue - dist = self.distance(flock[i]) - - if dist < self.SEPERATION_DISTANCE: - too_close.append([flock[i].pos_x, flock[i].pos_y]) - if dist < self.NEARBY_DISTANCE: - nearby_headings.append([flock[i].vel_x, flock[i].vel_y]) - nearby_positions.append([flock[i].pos_x, flock[i].pos_y]) - - if nearby_positions: - center_x = sum(p[0] for p in nearby_positions) / len(nearby_positions) - center_y = sum(p[1] for p in nearby_positions) / len(nearby_positions) - self.vel_x += (center_x - self.pos_x) * .08 - self.vel_y += (center_y - self.pos_y) * .08 - - if nearby_headings: - avg_x = sum(p[0] for p in nearby_headings) / len(nearby_headings) - avg_y = sum(p[1] for p in nearby_headings) / len(nearby_headings) - self.vel_x += (avg_x - self.vel_x) * .02 - self.vel_y += (avg_y - self.vel_y) * .02 - - sep_x = 0 - sep_y = 0 - - for pos in too_close: - sep_x += self.pos_x - pos[0] - sep_y += self.pos_y - pos[1] - - self.vel_x += sep_x * .04 - self.vel_y += sep_y * .04 - - vel_current = ((self.vel_x ** 2) + (self.vel_y ** 2)) ** .5 - - if vel_current > self.max_velocity: - # make unit vector - self.vel_x /= vel_current - self.vel_y /= vel_current - - # make max speed - self.vel_x *= self.max_velocity - self.vel_y *= self.max_velocity - - current_time = time.time() - - self.vel_x += self.vel_x * (self.ACC * (current_time - self.last_time)) - self.vel_y += self.vel_y * (self.ACC * (current_time - self.last_time)) - - self.delta_x = self.vel_x * (current_time - self.last_time) - self.delta_y = self.vel_y * (current_time - self.last_time) - self.last_time = current_time - - - - - - - -pygame.init() - -display = pygame.display.set_mode((500,500)) - -flock = [] - -for i in range(NUM_BOIDS): - flock.append(Boid()) - -while True: - - display.fill(red) - - - for boid in flock: - boid.compute_move(flock) - - for boid in flock: - boid.move() - boid.draw(display) - - pygame.display.update() diff --git a/movement/gravity.py b/movement/gravity.py @@ -1,111 +0,0 @@ -import pygame -import random -import time - -G = (6.674 * 10**-11) - -class Body(): - def __init__(self, x, y, mass, radius, vel_x, vel_y): - self.radius = radius - self.mass = mass - self.x = x - self.y = y - self.vel_x = vel_x - self.vel_y = vel_y - self.last_timestep = time.time() - - def distance(self, body): - return ((((self.x - body.x) ** 2) + ((self.y - body.y) ** 2)) ** .5) - - def render(self, display): - pygame.draw.circle(display, white, (self.x, self.y), self.radius) - - def get_delta_time(self): - current = time.time() - result = current - self.last_timestep - self.last_timestep = current - return result - - def update_position(self): - self.x += self.vel_x * self.delta_time - self.y += self.vel_y * self.delta_time - - def update_velocity(self, bodies): - self.delta_time = self.get_delta_time() - - m_1 = self.mass - - for body in bodies: - if body == self: - continue - r = self.distance(body) - - if r < self.radius + body.radius: - if body.mass > self.mass: - return False - - if r < 20: - continue - - m_2 = body.mass - - self.vel_x += ((G * m_2 / r ** 2) * (body.x - self.x) / r) * self.delta_time - self.vel_y += ((G * m_2 / r ** 2) * (body.y - self.y) / r) * self.delta_time - - if (self.x > 1200 and self.vel_x > 0) or (self.x < 0 and self.vel_x < 0): - self.vel_x *= -1 - if (self.y > 1000 and self.vel_y > 0) or (self.y < 0 and self.vel_y < 0): - self.vel_y *= -1 - - return True - - - - - - -pygame.init() - -display = pygame.display.set_mode((1200, 1000)) - -white = (255, 255, 255) -red = (255, 0, 0) -black = (0, 0, 0) - -bodies = [] - -for i in range(0,200): - # would be better to calculate radius, volume, and then use this to calculate mass - size_rnd = random.random() * .25 - size = (4.2 * 10**15) * size_rnd - radius = size_rnd * 10 - bodies.append(Body(random.randint(0,1200), random.randint(0,1000), size, radius, random.randint(-100,100), random.randint(-100,100))) - -size = (4.2 * 10**15) * 10 -radius = 100 - -bodies.append(Body(600, 500, size, radius, 0,0)) - -while True: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - pygame.quit() - quit() - - display.fill(black) - - to_remove = [] - - for body in bodies: - if not body.update_velocity(bodies): - to_remove.append(body) - - for body in to_remove: - bodies.remove(body) - - for body in bodies: - body.update_position() - body.render(display) - - - pygame.display.update() diff --git a/movement/seek.py b/movement/seek.py @@ -1,73 +0,0 @@ -import pygame -import time - - -player_pos = (100, 100) -agent_pos = (200, 200) -agent_speed = 100 -player_speed = 200 - -pygame.init() - -screen_width = 800 -screen_height = 600 -screen = pygame.display.set_mode((screen_width, screen_height)) - -black = (0, 0, 0) -white = (255, 255, 255) - -running = True -last_time = time.time() - - -def draw_players(): - pygame.draw.circle(screen, white, player_pos, 10) - pygame.draw.circle(screen, white, agent_pos, 10) - -def vector_length(p1): - return (p1[0]**2 + p1[1]**2)**0.5 - -left = False - -while running: - for event in pygame.event.get(): - if event.type == pygame.QUIT: - running = False - - current_time = time.time() - time_delta = current_time - last_time - last_time = current_time - - position_delta = player_pos[0] - agent_pos[0], player_pos[1] - agent_pos[1] - - agent_pos = ( - agent_pos[0] + ((position_delta[0] / vector_length(position_delta)) * time_delta * agent_speed), - agent_pos[1] + ((position_delta[1] / vector_length(position_delta)) * time_delta * agent_speed), - ) - - - player_delta = (0,0) - - - if player_pos[0] > screen_width and not left: - left = True - - if player_pos[0] < 0 and left: - left = False - - if left: - player_delta = (-player_speed,0) - else: - player_delta = (player_speed,0) - - - player_pos = ( - player_pos[0] + player_delta[0] * time_delta, - player_pos[1] + player_delta[1] * time_delta - ) - - screen.fill(black) - draw_players() - pygame.display.update() - -pygame.quit() diff --git a/background/src/background.cpp b/src/background.cpp diff --git a/background/src/edge.cpp b/src/edge.cpp diff --git a/background/src/graph.cpp b/src/graph.cpp diff --git a/background/src/main.cpp b/src/main.cpp diff --git a/background/src/prim.cpp b/src/prim.cpp diff --git a/background/src/utils.cpp b/src/utils.cpp diff --git a/background/src/vertex.cpp b/src/vertex.cpp diff --git a/background/tests/algo_test.cpp b/tests/algo_test.cpp diff --git a/background/tests/graph_test.cpp b/tests/graph_test.cpp diff --git a/background/vendor/argparse.hpp b/vendor/argparse.hpp