xxxxxxxxxx
//further extension and exploration of mathematical marbling alogrithms,
//as laid out in Daniel Shiffman's Coding train video on the topic- https://thecodingtrain.com/challenges/183-mathematical-marbling
let drops = []
let shapes = []
let colors = ["#e70617", "#c15a01", "#458075", "#57d0c9", "#b7667d", "#ee80b3", "#b92b09", "#030003"]
let VerticesNO = 300
let xLine, yLine, bgColor, xdiv
let x = 0
let noiseAmount
function setup() {
let m = min(windowWidth, windowHeight)
createCanvas(m, m);
noiseAmount = height / 20
let bgIndex = floor(random(colors.length))
bgColor = colors[bgIndex]
colors.splice(bgIndex, 1)
shuffle(colors, true)
for (let y = noiseAmount * 1.5; y < height - noiseAmount; y += noiseAmount * 2) {
let pts = []
for (let x = width * 0.1; x < width * 0.9; x += width / 150) {
let pt = createVector(x, y)
pts.push(pt)
}
for (let x = width * 0.9; x > width * 0.1; x -= width / 150) {
let pt = createVector(x, y + noiseAmount)
pts.push(pt)
}
shapes.push(new shape(pts, colors[3]))
}
}
function draw() {
clear()
background(bgColor)
if (frameCount == 50) {
for (let y = noiseAmount * 2; y < height; y += noiseAmount) {
let x = noise(y, frameCount) * width
let r = random(noiseAmount * 0.1, noiseAmount * 0.3)
addInk(x, y, r, colors[0])
}
}
if (frameCount == 75) {
for (let y = noiseAmount * 2; y < height; y += noiseAmount) {
let x = noise(y, frameCount) * width
let r = random(noiseAmount * 0.05, noiseAmount * 0.15)
addInk(x, y, r, colors[1])
}
}
if (frameCount > 100) {
addInk(random(width * 0.1, width * 0.9), random(height), random(4), random(colors))
}
if (frameCount == 150) {
noLoop()
}
for (let s of shapes) {
s.show()
}
for (let d of drops) {
d.grow()
d.show()
}
}
function addInk(x, y, r, color) {
let droppy = new drop(x, y, r, color)
for (let other of drops) {
other.marble(droppy)
}
for (let s of shapes) {
s.marble(droppy)
}
drops.push(droppy)
}
class shape {
constructor(pts, color) {
this.points = pts
this.color = color
}
tine(m, x, y, z, c) {
let u = 1 / pow(2, 1 / c)
for (let pt of this.points) {
let b = createVector(x, y)
let pb = p5.Vector.sub(pt, b)
let n = m.copy().rotate(HALF_PI)
let d = abs(pb.dot(n))
let mag = z * pow(u, d)
pt.add(m.copy().mult(mag))
}
}
marble(other) {
for (let pt of this.points) {
let c = other.pos
let p = pt.copy()
let r = other.r
p.sub(c)
let m = p.mag()
let root = sqrt(1 + (r * r) / (m * m))
p.mult(root)
p.add(c)
pt.set(p)
}
}
show() {
fill(this.color)
stroke(this.color)
beginShape()
for (let i = 0; i < this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y)
}
endShape()
}
}
class drop {
constructor(x, y, r, color) {
this.pos = createVector(x, y)
this.r = 1
this.finalR = r
this.color = color
this.stroke = random(colors)
this.points = []
for (let i = 0; i < VerticesNO; i++) {
let angle = map(i, 0, VerticesNO, 0, TAU)
let v = createVector(x + cos(angle) * r, y + sin(angle) * r)
this.points.push(v)
}
}
grow() {
if (this.r < this.finalR) {
this.r += 0.25
for (let other of drops) {
other.marble(this)
}
for (let s of shapes) {
s.marble(this)
}
}
}
marble(other) {
for (let pt of this.points) {
let c = other.pos
let p = pt.copy()
let r = other.r
p.sub(c)
let m = p.mag()
let root = sqrt(1 + (r * r) / (m * m))
p.mult(root)
p.add(c)
pt.set(p)
}
}
show() {
fill(this.color)
noStroke()
beginShape()
for (let i = 0; i < this.points.length; i++) {
vertex(this.points[i].x, this.points[i].y)
}
endShape()
}
}