xxxxxxxxxx
252
//I know som of this stuff is standard
//but I like to implement it for practice
class Vec2 {
constructor(x, y){
this.x = x;
this.y = y;
}
}
function cerp(y1, y2, mu){
let mu2 = (1-cos(mu*PI))/2;
return(y1*(1-mu2)+y2*mu2);
}
class HeightTracker {
constructor(start, range, min, max){
this.start = start;
this.end = this.start + (random(range) - (range/2));
this.idx = 0;
this.step = 0.01;
this.range = range;
this.min = min;
this.max = max;
this.original = start;
}
next(){
let result = cerp(this.start, this.end, this.idx);
if (result > this.max || result < this.min){
this.start = result;
this.end = this.original;
this.idx = 0.1;
return result;
}
this.idx += this.step;
if (this.idx >= 1){
this.idx = 0;
this.start = this.end;
this.end = this.end + (random(this.range) - this.range/2);
}
return result;
}
}
function posVec(v){
return new Vec2(v.x + width/2, -v.y + height/2);
}
function polarToCart(v){
return new Vec2(v.x * cos(v.y), v.x * sin(v.y));
}
function cartToPolar(v){
let length = sqrt(v.x * v.x + v.y * v.y);
return new Vec2(length, atan2(v.y, v.x));
}
//Translate the vector v by w
function ptranslate(v, w){
return new Vec2(v.x + w.x, v.y + w.y);
}
function pdiff(v, w){
return new Vec2(w.x - v.x, w.y - v.y);
}
function pline(start, end){
let v = posVec(start);
let w = posVec(end);
line(v.x, v.y, w.x, w.y);
}
function pSmoothLine(start, end){
if (end.x < start.x){
let t = start;
start = end;
end = t;
}
if (abs(start.x - end.x) < 4){
pline(start, end);
return;
}
let y = start.y;
let oy = y;
let ox = start.x;
for(let x = start.x; x <= end.x; x+=1){
y = ((end.y - start.y) * smoothstep(start.x, end.x, x)) + start.y;
pline(new Vec2(ox, oy), new Vec2(x, y));
ox = x;
oy = y;
}
}
function smoothstep(edge0, edge1, x) {
// Scale, bias and saturate x to 0..1 range
x = clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0);
// Evaluate polynomial
return x * x * (3 - 2 * x);
}
function clamp(x, lowerlimit, upperlimit) {
if (x < lowerlimit)
x = lowerlimit;
if (x > upperlimit)
x = upperlimit;
return x;
}
function pcircle(v, diameter){
let w = posVec(v);
circle(w.x, w.y, diameter);
}
function linkCircle(v, w, diameter){
let u = cartToPolar(pdiff(v, w));
u.x = u.x - diameter/2;
let q = new Vec2(diameter/2, u.y);
let start = ptranslate(v, polarToCart(q));
let end = ptranslate(v, polarToCart(u));
if (start.x > end.x){
let t = start;
start = end;
end = t;
}
//pline(start,end);
pSmoothLine(start, end);
}
function pvector(p){
let origin = new Vec2(0, 0);
pline(new Vec2(0, 0), p);
let polar = cartToPolar(p);
let tip1 = polar.y + PI/50;
let tip2 = polar.y - PI/50;
let w = new Vec2(polar.x-20, tip1);
let u = new Vec2(polar.x-20, tip2);
pline(p, polarToCart(w));
pline(p, polarToCart(u));
pline(polarToCart(u), polarToCart(w));
}
function drawGrid(){
stroke(color(0xaa, 0xaa, 0xaa));
for(i = -width; i <= width; i+=10){
pline(new Vec2(i, -height), new Vec2(i, height));
}
for(i = -height; i <= height; i+=10){
pline(new Vec2(-width,i), new Vec2(width, i));
}
stroke(color(0, 0, 0));
pline(new Vec2(-width, 1), new Vec2(width, 1));
pline(new Vec2(1, -height), new Vec2(1, height));
pline(new Vec2(-width, 0), new Vec2(width, 0));
pline(new Vec2(0, -height), new Vec2(0, height));
pline(new Vec2(-width, -1), new Vec2(width, -1));
pline(new Vec2(-1, -height), new Vec2(-1, height));
for(i = -width; i <= width; i+=10){
pline(new Vec2(i, -5), new Vec2(i, 5));
}
for(i = -height; i <= height; i+=10){
pline(new Vec2(-5,i), new Vec2(5, i));
}
}
let numNodes = 12;
let nodeDiameter = 5;
let nodeHeightNoise = [];
let thetaNoise = 0;
let debugGrid = false;
function setup() {
//noLoop();
createCanvas(400, 400);
for(let i = 0; i < numNodes; i++){
nodeHeightNoise.push(
new HeightTracker(100, 50, 50, 150));
}
}
//let theta = 0;
function draw() {
let origin = new Vec2(0, 0);
let trans = new Vec2(0, 100);
colorMode(RGB);
if (debugGrid){
background(220);
drawGrid();
fill(color(0xff, 0xff, 0xff, 10));
pcircle(origin, 300);
pcircle(origin, 100);
}
else {
background(75);
stroke(color(0xcc, 0x8A, 0x00));
}
colorMode(HSB, 2*PI, 100, 100);
// debug
/*
let u = new Vec2(100, 180);
let w = new Vec2(-120, -150);
theta += 0.01;
fill(color(0.25 * PI, 50, 80));
pcircle(u, 20);
fill(color(2.25 * PI, 50, 80));
pcircle(w, 20);
//pSmoothLine(u, w);
linkCircle(u, w, 20);
*/
// end debug
let theta = noise(thetaNoise);
thetaNoise += 0.0005;
let dColor = 1/numNodes;
let thetaColor = 0;
let v = polarToCart(new Vec2(nodeHeightNoise[0].next(), (2*PI) * theta));
let last = v;
fill(color(thetaColor * 2 * PI, 50, 80));
for(let i = 0; i < numNodes - 1; i++){
let w = cartToPolar(last);
w = ptranslate(w,
new Vec2(0, PI/(numNodes/2)));
w.x = nodeHeightNoise[i].next();
w = polarToCart(w);
pcircle(w, nodeDiameter);
linkCircle(w, last, nodeDiameter);
last = w;
fill(color(thetaColor * 2 * PI, 50, 80));
thetaColor += dColor;
}
pcircle(v, nodeDiameter);
linkCircle(last, v, nodeDiameter);
}