shithub: graphical-algorithms

Download patch

ref: f5f4fb16ed24308c78ba1fdc5e84cbcaba53c51c
author: phil9 <[email protected]>
date: Fri Dec 23 02:18:23 EST 2022

initial import

--- /dev/null
+++ b/README.md
@@ -1,0 +1,1 @@
+Some graphical algorithms implemented using ![slug]{https://github.com/telephil9/slug}.
--- /dev/null
+++ b/marching-squares
@@ -1,0 +1,70 @@
+#!/bin/slug
+
+-- Implementation of the marching squares algorithm
+-- see https://en.wikipedia.org/wiki/Marching_squares
+
+ROWS = 100
+COLS = 100
+mt = {}
+
+function b(a, b, c, d)
+	return a*8 + b*4 + c*2 + d
+end
+
+function setup()
+	size(1000, 1000)
+	background(235)
+	stroke(0)
+	strokeWeight(1)
+	for y = 1, ROWS+1 do
+		mt[y] = {}
+		for x = 1, COLS+1 do
+			v = 0
+			if math.random() >= 0.5 then v = 1 end
+			mt[y][x] = v
+		end
+	end
+
+	cx = width / ROWS
+	cy = height / COLS
+	for y = 0, ROWS-1 do
+		for x = 0, COLS-1 do
+			n = b(mt[y+1][x+1], mt[y+1][x+2], mt[y+2][x+2], mt[y+2][x+1])
+			if n == 1 then
+				line(x*cx, (y+0.5)*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 2 then
+				line((x+1)*cx, (y+0.5)*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 3 then
+				line(x*cx, (y+0.5)*cy, (x+1)*cx, (y+0.5)*cy)
+			elseif n == 4 then
+				line((x+0.5)*cx, (y+0)*cy, (x+1)*cx, (y+0.5)*cy)
+			elseif n == 5 then
+				line((x)*cx, (y+0.5)*cy, (x+0.5)*cx, (y)*cy)
+				line((x+0.5)*cx, (y+1)*cy, (x+1)*cx, (y+0.5)*cy)
+			elseif n == 6 then
+				line((x+0.5)*cx, y*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 7 then
+				line(x*cx, (y+0.5)*cy, (x+0.5)*cx, y*cy)
+			elseif n == 8 then
+				line(x*cx, (y+0.5)*cy, (x+0.5)*cx, y*cy)
+			elseif n == 9 then
+				line((x+0.5)*cx, y*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 10 then
+				line((x+0.5)*cx, (y+0)*cy, (x+1)*cx, (y+0.5)*cy)
+				line(x*cx, (y+0.5)*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 11 then
+				line((x+0.5)*cx, (y+0)*cy, (x+1)*cx, (y+0.5)*cy)
+			elseif n == 12 then
+				line(x*cx, (y+0.5)*cy, (x+1)*cx, (y+0.5)*cy)
+			elseif n == 13 then
+				line((x+1)*cx, (y+0.5)*cy, (x+0.5)*cx, (y+1)*cy)
+			elseif n == 14 then
+				line(x*cx, (y+0.5)*cy, (x+0.5)*cx, (y+1)*cy)
+			end
+		end
+	end
+end
+
+function draw()
+	noLoop()
+end
--- /dev/null
+++ b/sierpinski-chaos
@@ -1,0 +1,51 @@
+#!/bin/slug
+
+-- Sierpinski triangle generation using the chaos game algorithm
+-- see https://en.wikipedia.org/wiki/Sierpi%C5%84ski_triangle#Chaos_game
+
+x0 = 0
+y0 = 0
+x1 = 0
+y1 = 0
+x2 = 0
+y2 = 0
+x  = 0
+y  = 0
+
+function setup()
+	size(800, 800)
+	x0 = width/2
+	y0 = 0
+	x1 = 0
+	y1 = height
+	x2 = width
+	y2 = height
+	x  = math.floor(math.random(width))
+	y  = math.floor(math.random(height))
+	background(0)
+	strokeWeight(2)
+	strokeCap(ROUND)
+end
+
+function draw()
+	for i = 1, 10 do
+		r = math.floor(math.random(3)) - 1
+		if r == 0 then
+			stroke(255, 0, 0)
+			x = math.floor(0.5 + math.lerp(x, x0, 0.5))
+			y = math.floor(0.5 + math.lerp(y, y0, 0.5))
+			circle(x, y, 1)
+		elseif r == 1 then
+			stroke(0, 255, 0)
+			x = math.floor(0.5 + math.lerp(x, x1, 0.5))
+			y = math.floor(0.5 + math.lerp(y, y1, 0.5))
+			circle(x, y, 1)
+		elseif r == 2 then
+			stroke(0, 0, 255)
+			x = math.floor(0.5 + math.lerp(x, x2, 0.5))
+			y = math.floor(0.5 + math.lerp(y, y2, 0.5))
+			circle(x, y, 1)
+		end
+	end
+end
+
--- /dev/null
+++ b/sierpinski-lsystem
@@ -1,0 +1,59 @@
+#!/bin/slug
+
+-- Sierpinski triangle generation using an L-System
+-- see https://en.wikipedia.org/wiki/L-system#Example_5:_Sierpinski_triangle
+
+gen = 0
+start = "F-G-G"
+rules = { F="F-G+F+G-F", G="GG" }
+angle = 120
+len = 50
+current = start
+x = 0
+y = 0
+
+function setup()
+	size(1600, 1400)
+end
+
+function evolve()
+	gen = gen + 1
+	next = ""
+	for i = 1, #current do
+		c = string.sub(current, i, i)
+		r = rules[c]
+		if r ~= nil then
+			next = next .. r
+		else
+			next = next .. c
+		end
+	end
+	current = next
+end
+
+function draw()
+	if gen == 6 then
+		noLoop()
+		return
+	end
+	evolve()
+	background(0)
+	stroke(255)
+	strokeWeight(1)
+	x = width / 2
+	y = height-10
+	for i = 1, #current do
+		c = string.sub(current, i, i)
+		if c == "F" or c == "G" then
+			nx = math.floor(0.5 + x + len * math.cos(radians(angle)))
+			ny = math.floor(0.5 + y + len * math.sin(radians(angle)))
+			line(x, y, nx, ny)
+			x = nx
+			y = ny
+		elseif c == "+" then
+			angle = angle - 120
+		elseif c == "-" then
+			angle = angle + 120
+		end
+	end
+end