Skip to content

Triangle strider

An experiment in self-avoiding walks. Also, having fun with JavaScript's splat operator.

A spider-like creature darts around a hexagonal grid, avoiding stepping on places where it's stepped before.

let c
function setup() {
  c = createCanvas(windowWidth, windowHeight);
  c.mouseWheel(mouseWheelCanvas)
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  
}

let sq3 = Math.sqrt(3)

function hts(x, y, z) { // Hex to screen - inspired by https://www.redblobgames.com/grids/hexagons/#coordinates
  return [
    x * -sq3/2 + y * 0 + z * sq3/2,
    x * -1/2 + y * 1 + z * -1/2,
  ]
}
function sth(a, b) { // Screen to hex
  let y = b / 3 * 2
  let x = -(a / sq3) - y / 2
  return [
    x,
    y,
    -x-y
  ]
}

let p = [0, 0, 0]
let visited = {}
let visitedPoints = []
let cam = [0, 0]
let recent = []
let s = 10

function mouseWheelCanvas(event) {
  s += Math.sign(event.deltaY) * -1
  s = max(s, 1)
}

function draw() {
  background(220);
  
  translate(width / 2, height / 2)
  scale(s)
  let pS = hts(...p)
  for (let i = 0; i < 2; i ++) cam[i] = cam[i] + (pS[i] - cam[i]) * 0.005 * s
  translate(-(cam[0]), -(cam[1]))
  noFill()
  
  let mouseP = sth((mouseX - width / 2) / s + cam[0], (mouseY - height / 2) / s + cam[1])
  
  for (let i = 0; i < 10 / s; i ++) {
    let minP = p
    let minC = Infinity
    for (let j = -3; j < 3; j ++) {
      let np = [...p]
      np[(j + 3) % 3] += (j < 0 ? -1 : 1)
      np[(j + 4) % 3] += -(j < 0 ? -1 : 1)
      let c = (visited[np]|0)
      c += ((mouseP[(j + 3) % 3] - p[(j + 3) % 3]) * (j < 0 ? 1 : -1)) > 0 ? 0.08 : 0
      c += random() * 0.5
      if (c < minC) {
        minC = c
        minP = np
      }
    }
    if (!visited[p]) visitedPoints.push(p)
    visited[p] = (visited[p]|0) + 1
    p = minP
    recent.push(p)
    if (recent.length > 30) recent.shift()
  }
  
  
  for (let i = 1; i < recent.length; i ++) {
    stroke(map(i, 0, recent.length, 220, 100))
    strokeWeight(1)
    line(...hts(...recent[i - 1]), ...hts(...recent[i]))
  }
  for (let k of visitedPoints) {
    stroke(100)
    strokeWeight(visited[k] / 2)
    point(...hts(...k))
  }
  for (let i = max(recent.length - 8, 0); i < recent.length; i ++) {
    stroke(0)
    strokeWeight(0.3)
    line(...hts(...p), ...hts(...recent[i]))
  }
}

(Originally seen at https://editor.p5js.org/bojidar-bg/sketches/2rOPGKJMO)

Experiments tagged p5 (53/85)

Experiments tagged interactive (17/26)

Experiments on this site (53/85)