Experimenting with attractors - bis.
Log in to post a comment.
// You can find the Turtle API reference here: https://turtletoy.net/syntax
Canvas.setpenopacity(0.5);
const size = 160; //min = 100, max = 200, step = 1
//const lines = 40; //min = 1, max = 250, step = 1
const hLines = 00; //min = 0, max = 250, step = 1
const vLines = 120; //min = 0, max = 250, step = 1
const randomLines = 0; //min = 0, max = 1000, step = 1
//const force = 30; // min = -200, max = 200, step = 1
const attractors = 3; //min = 1, max = 50, step = 1
const attractorsFieldSize = 120; //min = 40, max = 200, step = 1
const resolution = 0.1; //min = 0.01, max = 1, step = 0.01
// help function to compute the distance from a point (i.e., the hypothenuse of a triangle rectangle)
function distance(x, y){
return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
}
// An attractor is a point which deflects drawing. It has a position and a force.
class Attractor{
constructor(x = 0, y = 0, force = 0){
this.x = x;
this.y = y;
this.force = force;
if( x == 0 && y == 0 && force == 0){
this.x = Math.random() * attractorsFieldSize - attractorsFieldSize / 2;
this.y = Math.random() * attractorsFieldSize - attractorsFieldSize / 2;
this.force = Math.random() * 200;
}
}
}
class Line{
constructor(a, b, c, d, att){
this.xs = a;
this.ys = b;
this.xe = c;
this.ye = d;
this.attractors = att;
this.turtle = new Turtle();
this.turtle.jump(a, b);
this.deltaX = c - a;
this.deltaY = d - b;
this.x = a;
this.y = b;
this.index = 0;
this.limit = size / resolution;
this.incX = this.deltaX / this.limit;
this.incY = this.deltaY / this.limit;
}
walk(){
this.x = this.xs + this.incX * this.index;
this.y = this.ys + this.incY * this.index;
if(this.attractors){
let delta;
let coef;
for(let item of this.attractors){
let deltaX = this.x - item.x;
let deltaY = this.y - item.y;
delta = distance(deltaX, deltaY);
coef = Math.pow(item.force/delta, 2);
let moveX = (deltaX / delta) * coef;
let moveY = (deltaY / delta) * coef;
let dist = distance(moveX, moveY);
if(dist > delta){
moveX = deltaX;
moveY = deltaY;
}
this.x -= moveX;
this.y -= moveY;
}
}
// this.x += this.incX;
// this.y += this.incY;
if(this.index == 0) this.turtle.jump(this.x, this.y)
else this.turtle.goto(this.x, this.y);
if(this.index++ < this.limit) return true;
return false;
}
}
// generate random attractors.
const attractorList = [];
for(let i = 0; i < attractors; i++){
attractorList.push(new Attractor());
}
const lineList = [];
// Start with horizontal Lines
for(let i = 0; i < hLines; i++){
let delta = size / (hLines - 1);
lineList.push(new Line(-size/2, -size/2 + i * delta, size/2, -size/2 + i * delta, attractorList));
// push random lines
}
// Then vertical lines
for(let i = 0; i < vLines; i++){
let delta = size / (vLines - 1);
lineList.push(new Line(-size/2 + i * delta, -size/2, -size/2 + i * delta, size/2, attractorList));
}
//random lines ?
for(let i = 0; i < randomLines; i++){
let delta = size / (randomLines - 1);
let a, b, c, d;
/*
if(Math.random() < 0.5){
a = -size / 2;
b = Math.random() * size - size / 2;
c = size / 2;
d = Math.random() * size - size / 2;
} else {
a = Math.random() * size - size / 2;
b = -size / 2;
c = Math.random() * size - size / 2;
d = size / 2;
}
lineList.push(new Line(a, b, c, d, attractorList));
*/
let p = [];
p.push(-size / 2);
p.push(Math.random() * size -size / 2);
p.push(size / 2);
p.push(Math.random() * size -size / 2);
let rand = Math.random();
// Choose one quadrant for starting the line
if(rand < 0.25){
// [p[0], p[2]] = [p[2], p[0]]; // no change : x is fixed and <0, y is random
} else if(rand < 0.5){
[p[0], p[1]] = [p[1], p[0]]; // x-y swap : x is random, y is fixed and < 0
} else if(rand < 0.75){
[p[0], p[2]] = [p[2], p[0]]; // x is fixed and > 0, y is random
} else {
[p[0], p[2]] = [p[2], p[0]]; // x is random, , y is fixed and > 0
[p[0], p[1]] = [p[1], p[0]];
}
// Then once the line is started it can land on the opposite side, or on an adjacent side.
if(Math.random() < 0.5) [p[2], p[3]] = [p[3], p[2]];
lineList.push(new Line(p[0], p[1], p[2], p[3], attractorList));
}
// The walk function will be called until it returns false.
function walk(i) {
let goOn = true;
for(let item of lineList){
goOn = item.walk();
}
return goOn;
}