A Fractal at Sunset - 2023 September 22
Click on the art piece to randomize it, or save the current URL to share it.
Click on the art piece to randomize it, or save the current URL to share it.
Edward Delaporte created this art using the P5.js JavaScript library, and the following additional code:
brickwall
function setup_canvas(maxim_x=800, maxim_y=400) {
  midline = maxim_x / 2;
  myCanvas = createCanvas(maxim_x, maxim_y);
}
function zippy() {
  /// Dark Striped Background
  noStroke();
  stripe_w = 60;
  for(i=0; i<400; i++) {
    fill(fresh_color(.3)); // darker fill color
    x = i * stripe_w;
    // triangle(x, y, x+30, y-random(80), x, y+i+30);
    rect(x,0, stripe_w, 400);
  }
}
function setup_background_circles(centerx, max_diam){
  xo = centerx;
  yo = centerx;
  for(var i=0; i<9; i++){
    ccolor = fresh_color();
    diam = max_diam -i*20;
    fill(ccolor);
    circle(xo, yo, diam);
  }
}
function starfield(max_x, max_y, star_size=4) {
  // white stars
  noStroke();
  fill(color(255,255,255));
  
  // Randomly scatter stars.
  starcount = random(20,60);
  for(i=0;i<starcount;i++){
    starx = random(0, max_x);
    stary = random(0, max_y);
    circle(starx, stary, star_size);
    if(random(0,5)==1) {
      circle(starx -4, stary -4, star_size);
    }
  }
}
  
    
/* 
Reusable random functions
*/
function rando_url(){
  if(get_url_seed() == null) {
    new_random(Date.now());
  }
}
function random_plus_minus(low, high){
  // Return a random number with a random sign
  var plus_minus = Math.random() < 0.5 ? -1 : 1;
  var sel_val = low + Math.random()*(high-low);
  return sel_val * plus_minus;
}
function new_random(seed=null) {
  seed = get_random_seed(seed);
  window.location.search = "?r=" + seed;
}
function get_url_seed() {
  const params = new URLSearchParams(location.search);
  seed = params.get('r');
  return seed;
}
function get_random_between(low, high, seed) {
  if(!seed) {
    seed = get_url_seed();
  }
  return low + get_random_from_seed(seed, high);
}
function get_random_seed(seed=200) {
  rand = Math.random();
  rand = Math.sin(seed) * 10000;
  seed = rand - Math.floor(rand);
  return seed;
}
function get_random_from_seed(seed, max_r=1) {
    rand = Math.sin(seed) * 10000;
    rand = rand - Math.floor(rand); // Get remainder
    return Math.floor(rand * max_r);
}
var color_shift = 0;
function fresh_color(warmth=.7, seed) {
  if(!seed) {
    seed = get_url_seed();
    color_shift+=1;
    seed = seed^color_shift;
  }
  r1 = get_random_from_seed(seed, 255);
  r2 = get_random_from_seed(seed*r1, 255);
  r3 = get_random_from_seed(seed*r2, 255);
  return color(r1*warmth,r2*warmth,r3*warmth);
}
function fresher_color(warmth=.7, seed) {
  if(!seed) {
    seed = get_url_seed();
    color_shift+=1;
    seed = seed^color_shift;
  }
  r1 = 85 + get_random_from_seed(seed^color_shift, 170);
  color_shift+=random();
  r2 = 85 + get_random_from_seed(seed^color_shift, 170);
  color_shift+=random();
  r3 = 85 + get_random_from_seed(seed^color_shift, 170);
  color_shift+=random();
  return color(r1*warmth,r2*warmth,r3*warmth);
}
function remove_item(choices, item) {
  index = choices.indexOf(item);
  if (index > -1) { 
    choices.splice(index, 1); 
  }
  return choices;
}
function choose(choices, seed) {
  // Support repeatable result.
  // so that every frame of animation re-uses the 
  // same choice as last.
  if(!seed) {
    seed = get_url_seed();
  }
  index = get_random_from_seed(seed, choices.length);
  return choices[index];
}
  
    
/*
"Horizon" is part of a Live Art work created by Edward Delaporte.
This script is Copyright Edward Delaporte 2021.
This script and the art it creates are licensed under 
a Creative Commons Attribution-ShareAlike 4.0 
International License.
http://creativecommons.org/licenses/by-sa/4.0/
You can share your own remix of this code 
as long as you display this license and attribution.
*/
var stripecount = 0;
var stripecolors = [];
function make_horizon(
  frame_minx, 
  frame_miny,
  frame_maxx,
  frame_maxy
) {
  var c = color(random(100,200),random(80,160), random(0,200));
  fill(c);
  stripecount = random(4,7);
  stripecolors = [];
  var stripefade = 20;
  var stripered = random(140, 200);
  var stripegreen = random(20, 100);
  var stripeblue = random(0, 200);
  for(i=0;i<stripecount;i++){
    c = color(stripered+i*stripefade,stripegreen+i*stripefade, stripeblue);
    stripecolors.push(c);
  }
  sund = random(30,50);
  sunx = random(frame_minx + sund, frame_maxx - sund);
  suny = random(frame_miny + sund, frame_maxy/2 - sund);
}
function draw_horizon(
  frame_minx, 
  frame_miny,
  frame_maxx,
  frame_maxy
  ) {
  fill(color(230,230,230));
  rect(frame_minx, frame_miny, 
    frame_maxx-frame_minx,
    frame_maxy-frame_miny);
  noStroke();
  var horiz_stripe_y;
  for(i=0;i<stripecount-1;i++){
    fill(stripecolors[i]);
    horiz_stripe_y = frame_miny + i*(frame_maxy/stripecount);
    rect(frame_minx, horiz_stripe_y, 
      frame_maxx - frame_minx, 
      frame_maxy - horiz_stripe_y - frame_miny);
  }
  // sun
  noStroke();
  fill(color(255,255,100));
  circle(sunx, suny, sund);
}
  
    
function toRadians (angle) {
  return angle * (Math.PI / 180);
}
function add_degrees(angle, degrees) {
  updated = angle + degrees;
  if(updated > 360) {
    updated = updated - 360;
  }
  return updated;
}
var line_segment = {
  x: 0,
  y: 0,
  weight: 4,
  degrees: 0,
  length: 20,
  history: 0,
  color: null,
  color_seq: [],
};
function draw_line_segment(line_seg, hide=0) {
  seg = structuredClone(line_seg);
  seg.history+=1;
  // stroke(seg.color.red, seg.color.green, seg.color.blue);
  strokeWeight(seg.weight);
  angleRad = toRadians(seg.degrees);
  endx = seg.x + seg.length*Math.cos(angleRad);
  endy = seg.y + seg.length*Math.sin(angleRad);
  if(hide==0) {
    line(seg.x, seg.y, endx, endy);
  }
  next_seg = structuredClone(seg);
  next_seg.x = endx;
  next_seg.y = endy;
  return next_seg;
}
function draw_line_cross(line_seg, dx, dy, hide=0) {
  seg = structuredClone(line_seg);
  seg.history+=1;
  strokeWeight(seg.weight);
  angleRad = toRadians(seg.degrees + 90);
  endx = seg.x + .5*seg.length*Math.cos(angleRad);
  endy = seg.y + .5*seg.length*Math.sin(angleRad);
  startx = seg.x - .5*seg.length*Math.cos(angleRad);
  starty = seg.y - .5*seg.length*Math.sin(angleRad);
  if(hide==0) line(startx+dx, starty+dy, 
    endx+dx, endy+dy);
  /*
  next_seg = structuredClone(seg);
  next_seg.x = endx;
  next_seg.y = endy;
  return next_seg;
  */
}
function draw_line_with_kite_shadow(line_seg, color_seq) {
  // prep
  seg = structuredClone(line_seg);
  angleRad = toRadians(seg.degrees);
  endx = seg.x + seg.length*Math.cos(angleRad);
  endy = seg.y + seg.length*Math.sin(angleRad);
  if(line_seg.history > 0) { // skip first line
  // draw shadow
  shadow_idx = (seg.history % color_seq.length);
  sha_c = color_seq[shadow_idx];
  stroke(sha_c.red, sha_c.green, sha_c.blue);
  fill(sha_c);
  swe = seg.weight*16;
  quad(
    seg.x,seg.y, 
    seg.x+swe,seg.y+swe, 
    endx,endy,
    endx+swe,endy+swe
    );
  // draw line
  stroke(seg.color.red, seg.color.green, seg.color.blue);
  strokeWeight(seg.weight);
  line(seg.x, seg.y, endx, endy);
  } else {
    endx = seg.x;
    endy = seg.y;
  }
  // house keeping
  seg.history+=1;
  next_seg = structuredClone(seg);
  next_seg.x = endx;
  next_seg.y = endy;
  return next_seg;
}
function new_line_segment(color_seq) {
  seg = structuredClone(line_segment);
  seg.color_seq = color_seq;
  seg.color = seg.color_seq[0];
  return seg;
}
  
    
/*
This is a Live Art work created by Edward Delaporte.
This script is Copyright Edward Delaporte 2021.
This script and the art it creates are licensed under 
a Creative Commons Attribution-ShareAlike 4.0 
International License.
http://creativecommons.org/licenses/by-sa/4.0/
You can share your own remix of this code 
as long as you display this license and attribution.
*/
var color_seq = [];
function start_fractal() {
  stroke(0,0,0);
  line_bit = new_line_segment([color(0,0,0)]);
  line_bit.length = 100;
  line_bit.x = 300;
  line_bit.y = 200;
  line_bit.degrees = random_plus_minus(30, 80); 
  roty = random(30, 72);
  an_count = 365 / roty;
  color_seq = [
    color(230,85,85),
    color(85,230,85),
    color(85,85,230),
  ];
  do_fractal(line_bit);
  for(i=0; i<an_count; i++) {
    line_bit.degrees += roty; 
    do_fractal(line_bit);
  }
}
var pri_angle = random_plus_minus(30, 60);
var sec_angle = random_plus_minus(45, 90);
async function do_fractal(bit) {
  const next_bit = structuredClone(
    draw_line_with_shadow(bit, color_seq));
  next_bit.length = next_bit.length*.67;
  next_bit.weight = next_bit.weight*.8;
  next_bit.degrees = add_degrees(bit.degrees, pri_angle);
  if(next_bit.length > 1) {
    await do_fractal(next_bit);
    const bit2 = structuredClone(next_bit);
    bit2.degrees = add_degrees(bit.degrees, sec_angle);
    await do_fractal(bit2);
  }
}
function setup() {
  // maxim = .5 * window.innderWidth;
  rando_url();
  maxim_x = 600;
  maxim_y = 400;
  midline = maxim_y / 2;
  myCanvas = createCanvas(maxim_x, maxim_y);
  /*
  background(0, 
    120+random_plus_minus(30,60), 
    150+random_plus_minus(30,60));
  */
  make_horizon(0,0,600,400);
  draw_horizon(0,0,600,400);
  start_fractal();
  console.log("setup done");
}
function mouseClicked() {
  new_random(get_url_seed());
}
function draw_line_with_shadow(line_seg, color_seq) {
  // prep
  seg = structuredClone(line_seg);
  angleRad = toRadians(seg.degrees);
  endx = seg.x + seg.length*Math.cos(angleRad);
  endy = seg.y + seg.length*Math.sin(angleRad);
  // draw shadow
  shadow_idx = (seg.history % color_seq.length);
  sha_c = color_seq[shadow_idx];
  ///stroke(sha_c.red, sha_c.green, sha_c.blue);
  noStroke();
  fill(sha_c);
  swe = seg.weight*4;
  quad(
    seg.x,seg.y, 
    endx,endy,
    endx+swe,endy+swe,
    seg.x+swe,seg.y+swe, 
    );
  // draw line
  stroke(seg.color.red, seg.color.green, seg.color.blue);
  strokeWeight(seg.weight);
  line(seg.x, seg.y, endx, endy);
  // house keeping
  seg.history+=1;
  next_seg = structuredClone(seg);
  next_seg.x = endx;
  next_seg.y = endy;
  return next_seg;
}
  
This work ©2020-2025 by Edward Delaporte is licensed under CC BY-NC-SA 4.0