├── README.md
├── bfs.js
├── bubblSort.js
├── dijkstra.js
├── dna.js
├── krish.jpeg
├── krishna.jpg
├── pixelDrawing.js
├── rainDrops.js
├── ramayana.png
├── snowfallCanvas.js
└── snowfallRamayana.js
/README.md:
--------------------------------------------------------------------------------
1 | ## Visuals based on various algorithms
2 |
3 | To run the code, open any file you like, copy and paste the code here and hit the play button at the top right corner
4 |
--------------------------------------------------------------------------------
/bfs.js:
--------------------------------------------------------------------------------
1 | let grid;
2 | let cols = 20;
3 | let rows = 20;
4 | let cellSize;
5 | let start, end;
6 | let openSet = [];
7 | let closedSet = [];
8 | let path = [];
9 | let current;
10 | let finished = false;
11 | let stepCounter = 0;
12 | let speed = 5; // Number of frames to wait before each step
13 | let lerpAmount = 5; // Amount for interpolation
14 |
15 | // New soothing color scheme
16 | let bgColor;
17 | let wallColor;
18 | let cellColor;
19 | let openSetColor;
20 | let closedSetColor;
21 | let pathColor;
22 | let connectionColor;
23 | let startColor;
24 | let endColor;
25 |
26 | function setup() {
27 | createCanvas(600, 600);
28 | cellSize = width / cols;
29 |
30 | // Initialize new color scheme
31 | bgColor = color(230, 230, 250); // Lavender mist
32 | wallColor = color(62.5); // Light steel blue
33 | cellColor = color(255, 255, 255, 150); // Semi-transparent white
34 | openSetColor = color(152, 251, 152, 200); // Pale green
35 | closedSetColor = color(255, 182, 193, 150); // Light pink
36 | pathColor = color(70, 130, 180); // Steel blue
37 | connectionColor = color(221, 160, 221, 150); // Plum
38 | startColor = color(50, 205, 50); // Lime green
39 | endColor = color(255, 99, 71); // Tomato
40 |
41 | // Create and initialize grid
42 | grid = Array.from({ length: cols }, (_, i) =>
43 | Array.from({ length: rows }, (_, j) => new Cell(i, j))
44 | );
45 |
46 | // Set neighbors
47 | for (let i = 0; i < cols; i++) {
48 | for (let j = 0; j < rows; j++) {
49 | grid[i][j].addNeighbors(grid);
50 | }
51 | }
52 |
53 | // Set start and end
54 | start = grid[0][0];
55 | end = grid[cols-1][rows-1];
56 |
57 | // Add walls randomly
58 | for (let i = 0; i < cols; i++) {
59 | for (let j = 0; j < rows; j++) {
60 | if (random(1) < 0.3) {
61 | grid[i][j].wall = true;
62 | }
63 | }
64 | }
65 | start.wall = false;
66 | end.wall = false;
67 |
68 | openSet.push(start);
69 | }
70 |
71 | function draw() {
72 | background(bgColor);
73 |
74 | if (!finished) {
75 | if (stepCounter % speed === 0) {
76 | // BFS algorithm step
77 | if (openSet.length > 0) {
78 | current = openSet.shift();
79 |
80 | if (current === end) {
81 | console.log("DONE!");
82 | finished = true;
83 | }
84 |
85 | closedSet.push(current);
86 |
87 | let neighbors = current.neighbors;
88 | for (let i = 0; i < neighbors.length; i++) {
89 | let neighbor = neighbors[i];
90 |
91 | if (!closedSet.includes(neighbor) && !neighbor.wall) {
92 | if (!openSet.includes(neighbor)) {
93 | openSet.push(neighbor);
94 | neighbor.previous = current;
95 | }
96 | }
97 | }
98 | } else {
99 | console.log("No solution");
100 | noLoop();
101 | return;
102 | }
103 |
104 | // Find path
105 | path = [];
106 | let temp = current;
107 | path.push(temp);
108 | while (temp.previous) {
109 | path.push(temp.previous);
110 | temp = temp.previous;
111 | }
112 | lerpAmount = 0; // Reset interpolation amount
113 | }
114 | stepCounter++;
115 | }
116 |
117 | // Interpolation update
118 | lerpAmount += 0.1; // Adjust speed of interpolation
119 | if (lerpAmount > 1) lerpAmount = 1;
120 |
121 | // Draw grid
122 | for (let i = 0; i < cols; i++) {
123 | for (let j = 0; j < rows; j++) {
124 | grid[i][j].show();
125 | }
126 | }
127 |
128 | // Draw path
129 | noFill();
130 | stroke(pathColor);
131 | strokeWeight(3);
132 | beginShape();
133 | for (let i = 0; i < path.length - 1; i++) {
134 | let x1 = path[i].i * cellSize + cellSize / 2;
135 | let y1 = path[i].j * cellSize + cellSize / 2;
136 | let x2 = path[i + 1].i * cellSize + cellSize / 2;
137 | let y2 = path[i + 1].j * cellSize + cellSize / 2;
138 | let lx = lerp(x1, x2, lerpAmount);
139 | let ly = lerp(y1, y2, lerpAmount);
140 | vertex(lx, ly);
141 | }
142 | endShape();
143 | }
144 |
145 | class Cell {
146 | constructor(i, j) {
147 | this.i = i;
148 | this.j = j;
149 | this.neighbors = [];
150 | this.previous = undefined;
151 | this.wall = false;
152 | }
153 |
154 | addNeighbors(grid) {
155 | let i = this.i;
156 | let j = this.j;
157 | if (i < cols - 1) this.neighbors.push(grid[i+1][j]);
158 | if (i > 0) this.neighbors.push(grid[i-1][j]);
159 | if (j < rows - 1) this.neighbors.push(grid[i][j+1]);
160 | if (j > 0) this.neighbors.push(grid[i][j-1]);
161 | }
162 |
163 | show() {
164 | stroke(100);
165 | strokeWeight(1);
166 | if (this.wall) {
167 | fill(wallColor);
168 | } else if (this === start) {
169 | fill(startColor);
170 | } else if (this === end) {
171 | fill(endColor);
172 | } else if (closedSet.includes(this)) {
173 | fill(closedSetColor);
174 | } else if (openSet.includes(this)) {
175 | fill(openSetColor);
176 | } else {
177 | fill(cellColor);
178 | }
179 | ellipse(this.i * cellSize + cellSize / 2, this.j * cellSize + cellSize / 2, cellSize * 0.7, cellSize * 0.7);
180 |
181 | // Connect to previous cell
182 | if (this.previous) {
183 | stroke(connectionColor);
184 | line(this.i * cellSize + cellSize / 2, this.j * cellSize + cellSize / 2,
185 | this.previous.i * cellSize + cellSize / 2, this.previous.j * cellSize + cellSize / 2);
186 | }
187 | }
188 | }
189 |
--------------------------------------------------------------------------------
/bubblSort.js:
--------------------------------------------------------------------------------
1 |
2 | let values = [];
3 | let i = 0;
4 | let j = 0;
5 | let sorted = false;
6 |
7 | function setup() {
8 | createCanvas(windowWidth, windowHeight);
9 | values = new Array(floor(width / 10)).fill().map(() => random(height));
10 | frameRate(30);
11 | }
12 |
13 | function draw() {
14 | background(30);
15 |
16 | if (!sorted) {
17 | if (i < values.length) {
18 | for (let k = 0; k < values.length - i - 1; k++) {
19 | let a = values[k];
20 | let b = values[k + 1];
21 |
22 | if (a > b) {
23 | values[k] = b;
24 | values[k + 1] = a;
25 | }
26 | }
27 | i++;
28 | } else {
29 | sorted = true;
30 | }
31 | }
32 |
33 | for (let i = 0; i < values.length; i++) {
34 | stroke(255);
35 | let col = map(values[i], 0, height, 0, 255);
36 | fill(col, 100, 255 - col, 150);
37 | rect(i * 10, height - values[i], 10, values[i], 5);
38 | }
39 |
40 | drawFrame();
41 | }
42 |
43 | function drawFrame() {
44 | strokeWeight(4);
45 | noFill();
46 | stroke(255);
47 | rect(0, 0, width, height);
48 | }
49 |
--------------------------------------------------------------------------------
/dijkstra.js:
--------------------------------------------------------------------------------
1 | let grid;
2 | let cols = 30;
3 | let rows = 30;
4 | let cellSize;
5 | let start, end;
6 | let openSet = [];
7 | let closedSet = [];
8 | let path = [];
9 | let current;
10 | let finished = false;
11 | let animationProgress = 0;
12 |
13 | // Apple-inspired color scheme
14 | let bgColor, cellColor, wallColor, openSetColor, closedSetColor, pathColor, startColor, endColor, gridColor;
15 |
16 | function setup() {
17 | createCanvas(600, 600);
18 | cellSize = min(width * 0.9 / cols, height * 0.9 / rows);
19 |
20 | // Initialize Apple-inspired color scheme
21 | bgColor = color(245, 245, 247);
22 | cellColor = color(255, 255, 255);
23 | wallColor = color(220, 220, 225);
24 | openSetColor = color(0, 122, 255, 150);
25 | closedSetColor = color(88, 86, 214, 100);
26 | pathColor = color(255, 149, 0);
27 | startColor = color(52, 199, 89);
28 | endColor = color(255, 59, 48);
29 | gridColor = color(230, 230, 230);
30 |
31 | initializeGrid();
32 | }
33 |
34 | function initializeGrid() {
35 | grid = Array.from({ length: cols }, (_, i) =>
36 | Array.from({ length: rows }, (_, j) => new Cell(i, j))
37 | );
38 |
39 | for (let i = 0; i < cols; i++) {
40 | for (let j = 0; j < rows; j++) {
41 | grid[i][j].addNeighbors(grid);
42 | }
43 | }
44 |
45 | start = grid[0][0];
46 | end = grid[cols-1][rows-1];
47 |
48 | for (let i = 0; i < cols; i++) {
49 | for (let j = 0; j < rows; j++) {
50 | if (random(1) < 0.3) {
51 | grid[i][j].wall = true;
52 | }
53 | }
54 | }
55 | start.wall = false;
56 | end.wall = false;
57 |
58 | start.distance = 0;
59 | openSet.push(start);
60 | }
61 |
62 | function draw() {
63 | background(bgColor);
64 | drawGrid();
65 | updateAlgorithm();
66 | drawPath();
67 | }
68 |
69 | function drawGrid() {
70 | let offsetX = (width - cols * cellSize) / 2;
71 | let offsetY = (height - rows * cellSize) / 2;
72 |
73 | for (let i = 0; i < cols; i++) {
74 | for (let j = 0; j < rows; j++) {
75 | grid[i][j].show(offsetX, offsetY);
76 | }
77 | }
78 | }
79 |
80 | function updateAlgorithm() {
81 | if (!finished && frameCount % 3 === 0) {
82 | if (openSet.length > 0) {
83 | current = openSet.reduce((a, b) => a.distance < b.distance ? a : b);
84 |
85 | if (current === end) {
86 | console.log("Path found!");
87 | finished = true;
88 | return;
89 | }
90 |
91 | openSet = openSet.filter(cell => cell !== current);
92 | closedSet.push(current);
93 |
94 | for (let neighbor of current.neighbors) {
95 | if (!closedSet.includes(neighbor) && !neighbor.wall) {
96 | let tentativeDistance = current.distance + 1;
97 |
98 | if (tentativeDistance < neighbor.distance) {
99 | neighbor.distance = tentativeDistance;
100 | neighbor.previous = current;
101 | if (!openSet.includes(neighbor)) {
102 | openSet.push(neighbor);
103 | }
104 | }
105 | }
106 | }
107 | } else {
108 | console.log("No path found");
109 | finished = true;
110 | return;
111 | }
112 |
113 | path = [];
114 | let temp = current;
115 | path.push(temp);
116 | while (temp.previous) {
117 | path.push(temp.previous);
118 | temp = temp.previous;
119 | }
120 | }
121 |
122 | animationProgress = lerp(animationProgress, 1, 0.1);
123 | }
124 |
125 | function drawPath() {
126 | if (path.length > 0) {
127 | let offsetX = (width - cols * cellSize) / 2;
128 | let offsetY = (height - rows * cellSize) / 2;
129 |
130 | noFill();
131 | stroke(pathColor);
132 | strokeWeight(cellSize / 3);
133 | beginShape();
134 | for (let i = 0; i < path.length * animationProgress; i++) {
135 | let cell = path[i];
136 | let x = offsetX + cell.i * cellSize + cellSize / 2;
137 | let y = offsetY + cell.j * cellSize + cellSize / 2;
138 | curveVertex(x, y);
139 | }
140 | endShape();
141 | }
142 | }
143 |
144 | class Cell {
145 | constructor(i, j) {
146 | this.i = i;
147 | this.j = j;
148 | this.neighbors = [];
149 | this.previous = undefined;
150 | this.wall = false;
151 | this.distance = Infinity;
152 | this.animationProgress = 0;
153 | }
154 |
155 | addNeighbors(grid) {
156 | let i = this.i;
157 | let j = this.j;
158 | if (i < cols - 1) this.neighbors.push(grid[i+1][j]);
159 | if (i > 0) this.neighbors.push(grid[i-1][j]);
160 | if (j < rows - 1) this.neighbors.push(grid[i][j+1]);
161 | if (j > 0) this.neighbors.push(grid[i][j-1]);
162 | }
163 |
164 | show(offsetX, offsetY) {
165 | let x = offsetX + this.i * cellSize;
166 | let y = offsetY + this.j * cellSize;
167 |
168 | if (this.wall) {
169 | fill(wallColor);
170 | } else if (this === start) {
171 | fill(startColor);
172 | } else if (this === end) {
173 | fill(endColor);
174 | } else if (closedSet.includes(this)) {
175 | fill(lerpColor(cellColor, closedSetColor, this.animationProgress));
176 | } else if (openSet.includes(this)) {
177 | fill(lerpColor(cellColor, openSetColor, this.animationProgress));
178 | } else {
179 | fill(cellColor);
180 | }
181 |
182 | noStroke();
183 | rect(x, y, cellSize, cellSize, cellSize / 4);
184 |
185 | if (closedSet.includes(this) || openSet.includes(this)) {
186 | this.animationProgress = lerp(this.animationProgress, 1, 0.1);
187 | }
188 | }
189 | }
190 |
191 | function heuristic(a, b) {
192 | return dist(a.i, a.j, b.i, b.j);
193 | }
194 |
--------------------------------------------------------------------------------
/dna.js:
--------------------------------------------------------------------------------
1 | function setup(){
2 | createCanvas(windowWidth,windowHeight);
3 | }
4 | let t = 0;
5 | function draw(){
6 | background('#0a6078');
7 | translate(width/2,-5*height);
8 | for(let i = 0;i<500;i++){
9 | strokeWeight(2);
10 | fill('#dadada');
11 | stroke('#dadada');
12 | line(xa1(t+i),ya1(t+i),xa2(t+i)+20,ya2(t+i)+20);
13 | circle(xa1(t+i),ya1(t+i),5);
14 | circle(xa2(t+i)+20,ya2(t+i)+20,5);
15 | strokeWeight(2);
16 | fill('#dadada');
17 | stroke('#dadada');
18 | line(x1(t+i),y1(t+i),x2(t+i)+20,y2(t+i)+20);
19 | circle(x1(t+i),y1(t+i),3);
20 | circle(x2(t+i)+20,y2(t+i)+20,3);
21 | }
22 | t+=0.075;
23 | }
24 |
25 | function x1(t){
26 | return sin(t/10)*100;
27 | }
28 |
29 | function y1(t){
30 | return (t/10)*100;
31 | }
32 |
33 | function x2(t){
34 | return -sin(t/10)*100;
35 | }
36 |
37 | function y2(t){
38 | return (t/10)*100;
39 | }
40 |
41 | function xa1(t){
42 | return -cos(t/10)*100;
43 | }
44 |
45 | function ya1(t){
46 | return (t/10)*100;
47 | }
48 |
49 | function xa2(t){
50 | return cos(t/10)*100;
51 | }
52 |
53 | function ya2(t){
54 | return (t/10)*100;
55 | }
56 |
57 | function xb1(t){
58 | return -((cos(t/10)+sin(t/10)))*100;
59 | }
60 |
61 | function yb1(t){
62 | return (t/10)*100;
63 | }
64 |
65 | function xb2(t){
66 | return ((cos(t/10)+sin(t/10)))*100;
67 | }
68 |
69 | function yb2(t){
70 | return (t/10)*100;
71 | }
72 |
--------------------------------------------------------------------------------
/krish.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoyron/algoVisuals/f8c42ad8444f0b48733f264963df3cbea57b078b/krish.jpeg
--------------------------------------------------------------------------------
/krishna.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zoyron/algoVisuals/f8c42ad8444f0b48733f264963df3cbea57b078b/krishna.jpg
--------------------------------------------------------------------------------
/pixelDrawing.js:
--------------------------------------------------------------------------------
1 | let img;
2 | let testImg;
3 | let points = [];
4 | const numPoints = 15000;
5 |
6 | function preload() {
7 | img = loadImage("./krishna.jpg");
8 | }
9 |
10 | function setup() {
11 | testImg = createImage(img.width, img.height);
12 | createCanvas(img.width, img.height);
13 | background(0);
14 | img.loadPixels();
15 | testImg.loadPixels();
16 | for (let i = 0; i < img.width; i++) {
17 | for (let j = 0; j < img.height; j++) {
18 | testImg.set(i, j, color(img.get(i, j)));
19 | }
20 | }
21 | testImg.updatePixels();
22 |
23 | for (let i = 0; i < numPoints; i++) {
24 | points.push(createVector(random(width), random(height)));
25 | }
26 | }
27 |
28 | function draw() {
29 | background(0, 10);
30 |
31 | for (let i = 0; i < points.length; i++) {
32 | let p = points[i];
33 |
34 | let angle = noise(p.x * 0.005, p.y * 0.005, frameCount * 0.01) * TWO_PI * 2;
35 | let speed = noise(p.x * 0.005, p.y * 0.005, frameCount * 0.01 + 1000) * 2;
36 |
37 | let newX = p.x + cos(angle) * speed;
38 | let newY = p.y + sin(angle) * speed;
39 |
40 | let c = testImg.get(int(p.x), int(p.y));
41 | stroke(c);
42 | strokeWeight(0.5);
43 | line(p.x, p.y, newX, newY);
44 |
45 | points[i].set(newX, newY);
46 |
47 | if (newX < 0 || newX > width || newY < 0 || newY > height) {
48 | points[i].set(random(width), random(height));
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/rainDrops.js:
--------------------------------------------------------------------------------
1 | class Rain{
2 | constructor(){
3 | this.x = random(-width,width);
4 | this.y = random(-height,height);
5 | this.z = random(width);
6 | }
7 |
8 | show(){
9 | fill(200, 200, 200);
10 | noStroke();
11 | this.sx = map(this.x/this.z,0,1,0,width);
12 | this.sy = map(this.y/this.z,0,1,0,height);
13 | this.r = map(this.z,0,width,8,0);
14 | circle(this.sx,this.sy,this.r);
15 | }
16 | update(){
17 | this.z = this.z-6;
18 | if(this.z<1){
19 | this.x = random(-width,width);
20 | this.y = random(-height,height);
21 | this.z = width;
22 | }
23 | }
24 | }
25 |
26 | let drops = [];
27 |
28 | function setup(){
29 | createCanvas(windowWidth,windowHeight);
30 | for(let i = 0;i<2500;i++){
31 | let tempo = new Rain();
32 | drops.push(tempo);
33 | }
34 | }
35 |
36 | function draw(){
37 | translate(width/2,height/2);
38 | background(0);
39 | for(let i = 0;i height) {
53 | let index = snowflakes.indexOf(this);
54 | snowflakes.splice(index, 1);
55 | }
56 | };
57 |
58 | this.display = function() {
59 | fill(color(img.get(this.posX, this.posY)));
60 | ellipse(this.posX, this.posY, this.size);
61 | };
62 | }
63 |
--------------------------------------------------------------------------------
/snowfallRamayana.js:
--------------------------------------------------------------------------------
1 | // snowflakes is an array of snowflake objects
2 | let snowflakes = [];
3 | let img;
4 | let xoff = 0;
5 | let scaleFactor = 7/10; // Scale factor for the canvas size
6 |
7 | // preload() is a special function in P5.js that runs once before setup()
8 | function preload() {
9 | // load the image (Ramayana.png) into the img variable
10 | img = loadImage('./ramayana.png');
11 | }
12 |
13 | // setup() is a special function in P5.js that runs once after preload()
14 | function setup() {
15 | // create a canvas with the same size as the image, but scaled down by scaleFactor
16 | createCanvas(img.width * scaleFactor, img.height * scaleFactor);
17 | // disable drawing outlines around shapes
18 | noStroke();
19 | // set the background color to black
20 | background("#000000");
21 | // set the frame rate to 45 frames per second
22 | frameRate(45);
23 | }
24 |
25 | // draw() is a special function in P5.js that runs continuously after setup()
26 | function draw() {
27 | // calculate the time since the last frame was drawn
28 | let t = frameCount / 90;
29 |
30 | // create a random number of snowflakes each frame
31 | for (let i = 0; i < random(50); i++) {
32 | // create a new snowflake object and add it to the snowflakes array
33 | snowflakes.push(new snowflake());
34 | }
35 |
36 | // loop through snowflakes with a for..of loop
37 | for (let flake of snowflakes) {
38 | // update the position of the snowflake
39 | flake.update(t);
40 | // draw the snowflake
41 | flake.display();
42 | }
43 |
44 | // increment xoff by 1.0 each frame
45 | xoff += 1.0;
46 | }
47 |
48 | // snowflake is a constructor function that creates a new snowflake object
49 | function snowflake() {
50 | // set the initial position of the snowflake
51 | this.posX = random(width);
52 | this.posY = random(-50, 0);
53 | // set the initial angle of the snowflake
54 | this.initialangle = random(0, 2 * PI);
55 | // set the size of the snowflake
56 | this.size = random(1, 3) * scaleFactor;
57 | // set the radius of the snowflake
58 | this.radius = sqrt(random(pow(width / 2, 2)));
59 |
60 | // update() is a method that updates the position of the snowflake
61 | this.update = function(time) {
62 | // angular speed
63 | let w = 1.6;
64 | // calculate the angle of the snowflake
65 | let angle = w * time + this.initialangle;
66 | // update the position of the snowflake
67 | this.posX = width / 2 + this.radius * sin(angle);
68 | this.posY += pow(this.size / scaleFactor, 0.5) * 2 * scaleFactor;
69 |
70 | // if the snowflake has gone off the bottom of the screen, remove it from the array
71 | if (this.posY > height) {
72 | let index = snowflakes.indexOf(this);
73 | snowflakes.splice(index, 1);
74 | }
75 | };
76 |
77 | // display() is a method that draws the snowflake
78 | this.display = function() {
79 | // calculate the x and y coordinates of the snowflake on the original image
80 | let imgX = this.posX / scaleFactor;
81 | let imgY = this.posY / scaleFactor;
82 | // get the color of the pixel at the calculated coordinates
83 | fill(color(img.get(imgX, imgY)));
84 | // draw an ellipse at the position of the snowflake
85 | ellipse(this.posX, this.posY, this.size);
86 | };
87 |
88 | }
89 |
--------------------------------------------------------------------------------