Skip to content

Commit

Permalink
Merge branch 'hackclub:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
splitlane authored Nov 15, 2024
2 parents 03bf01f + 81163c4 commit 87c364e
Show file tree
Hide file tree
Showing 49 changed files with 7,544 additions and 3 deletions.
1,060 changes: 1,060 additions & 0 deletions art/3D-Raycasting-Jaiden/index.js

Large diffs are not rendered by default.

Binary file added art/3D-Raycasting-Jaiden/snapshots/snapshot1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/3D-Raycasting-Jaiden/snapshots/snapshot2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/3D-Raycasting-Jaiden/snapshots/snapshot3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/3D-Raycasting-Jaiden/snapshots/snapshot4.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions art/BitMap-AdityaPV/Image_to_array_coverter.html
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
const outputInfo = document.getElementById('outputInfo');
outputInfo.innerHTML = '';

const maxWidth = 200;
const maxHeight = 200;
const maxWidth = 125;
const maxHeight = 125;

const img = new Image();
img.onload = function() {
Expand Down
94 changes: 94 additions & 0 deletions art/FlowingCurrents-KfirElyahu/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
@title: Flowing Currents
@author: Kfir Elyahu
@snapshot: 1.png
*/

// Set the dimensions of the drawing document
setDocDimensions(125, 125);

const { Turtle, noise, rand, randInRange, randIntInRange, setRandSeed, nurbs } = bt;

// Set a random seed
setRandSeed(randIntInRange(0, 1000000));

// Parameters
const GRID_SIZE = 30;
const CELL_SIZE = 125 / GRID_SIZE;
const NUM_LINES = 60;
const LINE_SEGMENTS = 20;
const NOISE_SCALE = 0.02;
const MARGIN = 2;
const MAX_OVERLAP = 2;

// Generate flow field using Perlin noise with random offset
const noiseOffset = randInRange(0, 1000);
const flowField = [];
for (let y = 0; y < GRID_SIZE; y++) {
for (let x = 0; x < GRID_SIZE; x++) {
const angle = noise([x * NOISE_SCALE + noiseOffset, y * NOISE_SCALE + noiseOffset]) * Math.PI * 2;
flowField.push([Math.cos(angle), Math.sin(angle)]);
}
}

// Function to get flow direction at a given point
function getFlowDirection(x, y) {
const gridX = Math.floor(x / CELL_SIZE);
const gridY = Math.floor(y / CELL_SIZE);
const index = gridY * GRID_SIZE + gridX;
return flowField[index] || [0, 0];
}

// Create a grid to track line density
const densityGrid = Array(GRID_SIZE).fill().map(() => Array(GRID_SIZE).fill(0));

// Function to update and check density
function updateDensity(x, y) {
const gridX = Math.floor(x / CELL_SIZE);
const gridY = Math.floor(y / CELL_SIZE);
if (gridX >= 0 && gridX < GRID_SIZE && gridY >= 0 && gridY < GRID_SIZE) {
densityGrid[gridY][gridX]++;
return densityGrid[gridY][gridX] <= MAX_OVERLAP;
}
return false;
}

// Generate flowing lines
const allLines = [];

for (let i = 0; i < NUM_LINES; i++) {
const turtle = new Turtle();
turtle.jump([randInRange(MARGIN, 125 - MARGIN), randInRange(MARGIN, 125 - MARGIN)]);
turtle.down();

const points = [turtle.pos];
let canContinue = true;

for (let j = 0; j < LINE_SEGMENTS && canContinue; j++) {
const [x, y] = turtle.pos;
const [dx, dy] = getFlowDirection(x, y);

turtle.setAngle(Math.atan2(dy, dx) * 180 / Math.PI);
turtle.forward(CELL_SIZE * 0.8); // Move 80% of a cell size to create some overlap between cells

// Keep the turtle within bounds and check density
let [newX, newY] = turtle.pos;
newX = Math.max(MARGIN, Math.min(125 - MARGIN, newX));
newY = Math.max(MARGIN, Math.min(125 - MARGIN, newY));

canContinue = updateDensity(newX, newY);
if (canContinue) {
turtle.jump([newX, newY]);
points.push(turtle.pos);
}
}

if (points.length > 2) {
// Generate a smooth curve through the points
const smoothLine = nurbs(points, { steps: 100 }); // Reduced steps for smaller drawing
allLines.push(smoothLine);
}
}

// Draw all lines
drawLines(allLines);
Binary file added art/FlowingCurrents-KfirElyahu/snapshots/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/FlowingCurrents-KfirElyahu/snapshots/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/FlowingCurrents-KfirElyahu/snapshots/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
194 changes: 194 additions & 0 deletions art/LineyPeaks-Jannik/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
/*
@title: LineyPeaks
@author: Jannik
@snapshot: 1.png
*/

// SETTINGS
const GRID_SIZE = 125;
const INFLUENCE_SCALE = 20; // How much the points influence each other | Recommended: 20
const LINE_SCALE = 20; // Length of the lines | Recommended: 20

// Debugging
const DEBUGGING = false; // Legacy, was used to debug point placement
const VSCodeMode = false; // Toggle VSCode mode. I've create a small html page and imitated a few blot functions to get autocomplete and live reload

// Randomization
const HIDDEN_FUNCTION_ANGLE = bt.randIntInRange(0, 360);
const HIDDEN_FUNCTION_OFFSET = bt.randIntInRange(0, 10);
const HIDDEN_FUNCTION_SCALE = bt.randIntInRange(50, 150) / 100;
const HIDDEN_FUNCTION_COUNT = bt.randIntInRange(1, 3);

// Auto-calculated settings
const PADDING = GRID_SIZE / 5;
const RENDER_SIZE = GRID_SIZE + PADDING * 2;
const POINT_SPACING = RENDER_SIZE / 2;
const POINT_RESOLUTION = RENDER_SIZE / POINT_SPACING;

// The hidden function, must return a value between 0 and 1
function hiddenFunction(x, y) {
x = x * HIDDEN_FUNCTION_SCALE;
y = y * HIDDEN_FUNCTION_SCALE;
let sum = 0;

function theFunction(angle, offset) {
function rotatedX(x, y) {
return x * Math.cos(angle) + y * Math.sin(angle)
}

function rotatedY(x, y) {
return y * Math.cos(angle) - x * Math.sin(angle)
}

return ((Math.cos(0.1 * rotatedX(x, y) - offset + Math.sin(0.1 * rotatedY(x, y)))) / 2) + 0.5
}

for (let i = 0; i < HIDDEN_FUNCTION_COUNT; i++) {
sum += theFunction(HIDDEN_FUNCTION_ANGLE, HIDDEN_FUNCTION_OFFSET);
}

return sum / HIDDEN_FUNCTION_COUNT
}

// Drawing wrapper
if (!VSCodeMode) {
const turtle = new bt.Turtle();
turtle.down();

function drawLine(x1, y1, x2, y2) {
x1 = x1 - PADDING;
y1 = y1 - PADDING;
x2 = x2 - PADDING;
y2 = y2 - PADDING;

// Ignore if completely out of bounds
if ((x1 < 0 && x2 < 0) || (y1 < 0 && y2 < 0)) return
if ((x1 > GRID_SIZE && x2 > GRID_SIZE) || (y1 > GRID_SIZE && y2 > GRID_SIZE)) return

// Stay inside area
x2 = Math.min(GRID_SIZE - 1, Math.max(0, x2));
y2 = Math.min(GRID_SIZE - 1, Math.max(0, y2));
turtle.jump([x1, y1]);
turtle.goTo([x2, y2]);
}

globalThis.drawLine = drawLine;
globalThis.turtle = turtle;
}

// Estimate the influence (value in our case since mass = 0) at [x, y] "emitted" from [pointX, pointY]
function influence(x, y, pointX, pointY) {
const distance = Math.sqrt((x - pointX) ** 2 + (y - pointY) ** 2);

if (distance > INFLUENCE_SCALE) {
return 0
}

const value = Math.abs((distance / INFLUENCE_SCALE) ** 2 - 1);
return value * value * value / (Math.PI * Math.pow(INFLUENCE_SCALE, 8) / 4)
}

// Step 1: Place points on a grid, carrying a value from the hidden function for their location
const points = [];
const point_values = [];


for (let x = 2; x < RENDER_SIZE - 2; x += POINT_RESOLUTION) {
for (let y = 2; y < RENDER_SIZE - 2; y += POINT_RESOLUTION) {
const value = hiddenFunction(x, y);

points.push([x, y]);
point_values.push(value);

if (DEBUGGING) {
debugPoint(x, y, value);
}
}
}


// Step 2: Calculate a density map for every point for normalizing in step 3
const density_map = {};

for (const point of points) {
const x = point[0];
const y = point[1];


if (density_map[x] === undefined) {
density_map[x] = {};
}

let sum = 0;

for (const otherPoint of points) {
sum += influence(x, y, otherPoint[0], otherPoint[1]);
}

density_map[x][y] = sum;
}


// Step 3: Calculate what every point "experiences" from all other points combined (really slow, but works :) )
const restored_values = {};

for (const point of points) {
const x = point[0];
const y = point[1];


if (restored_values[x] === undefined) {
restored_values[x] = {};
}

let sum = 0;

for (let i = 0; i < points.length; i++) {
const point = points[i];
sum += influence(x, y, point[0], point[1]) * point_values[i] / density_map[point[0]][point[1]];
}

restored_values[x][y] = sum;
}


// Step 4: Now for every point, check where it wants to go (wants to go to lower density)
function calcDeltaAtPoint(x, y) {
const step = POINT_RESOLUTION

// Make sure we don't go out of boundaries
let dX;
let dY;

if (x === 2) {
dX = (restored_values[x + step][y] - restored_values[x][y]) / (step * 2);
} else if (x === RENDER_SIZE - 3) {
dX = (restored_values[x][y] - restored_values[x - step][y]) / (step * 2);
} else {
dX = (restored_values[x + step][y] - restored_values[x - step][y]) / step;
}

if (y === 2) {
dY = (restored_values[x][y + step] - restored_values[x][y]) / (step * 2);
} else if (y === RENDER_SIZE - 3) {
dY = (restored_values[x][y] - restored_values[x][y - step]) / (step * 2);
} else {
dY = (restored_values[x][y + step] - restored_values[x][y - step]) / step;
}

return [dX, dY]
}

for (let i = 0; i < points.length; i++) {
const point_loc = points[i];

const delta_change = calcDeltaAtPoint(point_loc[0], point_loc[1]);

drawLine(point_loc[0] - PADDING, point_loc[1] - PADDING, point_loc[0] - (delta_change[0] * LINE_SCALE) - PADDING, point_loc[1] - (delta_change[1] * LINE_SCALE) - PADDING);
}

if (!VSCodeMode) {
drawLines(turtle.path);
}

console.log("Done !");
Binary file added art/LineyPeaks-Jannik/snapshots/1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/LineyPeaks-Jannik/snapshots/2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added art/LineyPeaks-Jannik/snapshots/3.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 87c364e

Please sign in to comment.