Chains of non-overlapping squares arranged in different patterns
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(1);
// Global code will be evaluated once.
const turtle = new Turtle();
let seed = 1000; // min=1 max=1000000 step=1
const bits = 20;
const samples = 150000;
const mod = 1<<bits;
const boarder_gap = 10; // min = -20 max = 20 step = 1
const square1_size_min = 0; // min = 0 max = 40 step = 1
const square2_size_min = 0; // min = 0 max = 40 step = 1
const square1_size_max = 2; // min = 0 max = 40 step = 1
const square2_size_max = 3; // min = 0 max = 40 step = 1
const chain_length_min = 0; // min = 0 max = 100 step = 1
const chain_length_max = 20; // min = 0 max = 100 step = 1
const chain_size_min = 20; // min = 0 max = 20 step = 1
const chain_size_max = 100; // min = 20 max = 100 step = 1
const angle = 0; // min = 0 max = 360 step = 1
const num_attempted_chains = 1500; // min = 0 max = 3000 step = 1
const rot = 0.55; // min = 0 max = 2 step = 0.01
const organization = 2; //min=0 max=2 step=1 (Random, Linear, Circular)
let sc_list = [];
class Square{
constructor(sx, sy, sl) {
this.sx = sx;
this.sy = sy;
this.sl = sl;
}
draw() {
turtle.penup();
turtle.goto(this.sx + this.sl/2, this.sy + this.sl/2);
turtle.pendown();
turtle.goto(this.sx - this.sl/2, this.sy + this.sl/2);
turtle.goto(this.sx - this.sl/2, this.sy - this.sl/2);
turtle.goto(this.sx + this.sl/2, this.sy - this.sl/2);
turtle.goto(this.sx + this.sl/2, this.sy + this.sl/2);
}
intersects(other) {
// if rectangle has area 0, no overlap
if (this.sl == 0 || other.sl == 0)
return false;
// If one rectangle is on left side of other
if (this.sx - this.sl / 2 > other.sx + other.sl / 2 || this.sx + this.sl / 2 < other.sx - other.sl / 2) {
return false;
}
// If one rectangle is above other
if (this.sy - this.sl / 2 > other.sy + other.sl / 2 || this.sy + this.sl / 2 < other.sy - other.sl / 2) {
return false;
}
return true;
}
}
class SquareChain {
constructor(s1, s2, num_square) {
this.s1 = s1;
this.s2 = s2;
this.num_square = num_square;
this.list_square = [];
for(let i = 0; i <= this.num_square; i++) {
let sq = new Square(
interp(this.s1.sx, this.s2.sx, i, this.num_square),
interp(this.s1.sy, this.s2.sy, i, this.num_square),
interp(this.s1.sl, this.s2.sl, i, this.num_square))
this.list_square.push(sq);
}
}
draw() {
this.list_square.forEach((sq) => sq.draw());
}
intersects(other) {
for(let i = 0; i < this.list_square.length; i++) {
for(let j = 0; j < other.list_square.length; j++) {
if(this.list_square[i].intersects(other.list_square[j])) {
return true;
}
}
}
return false;
}
}
////////////////////////////////////////////////////////////////
// Pseudorandom number generator. Created by Reinder Nijhoff 2024
// https://turtletoy.net/turtle/a2274fd1fe
////////////////////////////////////////////////////////////////
function random() { // returns a number [0, 1[
let r = 1103515245 * (((seed+=12345) >> 1) ^ seed);
r = 1103515245 * (r ^ (r >> 3));
r = r ^ (r >> 16);
return (r % mod) / mod;
}
function interp(x1, x2, current_step, steps) {
let ratio = (steps - current_step) / steps;
return(x1 * ratio + x2 * (1 - ratio));
}
// The walk function will be called until it returns false.
function walk(i) {
let sc;
let x1 = random() * (200 - 2 * boarder_gap) - 100 + boarder_gap;
let y1 = random() * (200 - 2 * boarder_gap) - 100 + boarder_gap;
let size1 = random() * (square1_size_max - square1_size_min) + square1_size_min;
let chain_length = random() * (chain_length_max - chain_length_min) + chain_length_min;
let theta = 0;
if(organization == 0) {
theta = random() * 2 * Math.PI;
}
else if (organization == 1){
theta = angle * 2 * Math.PI / 360;
}
else {
theta = Math.atan(y1/x1);
if(x1 > 0) {
theta += Math.PI;
}
theta += rot;
}
let x2 = x1 + chain_length * Math.cos(theta);
let y2 = y1 + chain_length * Math.sin(theta);
// let x2 = random() * (200 - 2 * boarder_gap) - 100 + boarder_gap;
// let y2 = random() * (200 - 2 * boarder_gap) - 100 + boarder_gap;
let size2 = random() * (square2_size_max - square2_size_min) + square2_size_min;
let steps = Math.floor(random() * (chain_size_max - chain_size_min) + chain_size_min);
let s1 = new Square(x1, y1, size1);
let s2 = new Square(x2, y2, size2);
sc = new SquareChain(s1, s2, steps);
let overlap = false;
for(let j = 0; j < sc_list.length; j++) {
console.log(sc_list[j]);
overlap = overlap || sc.intersects(sc_list[j]);
}
if(!overlap) {
console.log(sc);
sc.draw();
sc_list.push(sc);
}
return i < num_attempted_chains;
}