diff --git a/public/bg/1.jpeg b/public/bg/1.jpeg deleted file mode 100644 index 87cf9f0..0000000 Binary files a/public/bg/1.jpeg and /dev/null differ diff --git a/public/bg/2.jpeg b/public/bg/2.jpeg deleted file mode 100644 index ddbc10d..0000000 Binary files a/public/bg/2.jpeg and /dev/null differ diff --git a/public/bg/3.jpeg b/public/bg/3.jpeg deleted file mode 100644 index aa60b26..0000000 Binary files a/public/bg/3.jpeg and /dev/null differ diff --git a/public/bg/bg1_1.png b/public/bg/bg1_1.png new file mode 100644 index 0000000..d2fe2a9 Binary files /dev/null and b/public/bg/bg1_1.png differ diff --git a/public/bg/bg1_2.png b/public/bg/bg1_2.png new file mode 100644 index 0000000..547bb48 Binary files /dev/null and b/public/bg/bg1_2.png differ diff --git a/public/bg/bg1_3.png b/public/bg/bg1_3.png new file mode 100644 index 0000000..f7697ee Binary files /dev/null and b/public/bg/bg1_3.png differ diff --git a/public/bg/bg1_4.png b/public/bg/bg1_4.png new file mode 100644 index 0000000..ec21db4 Binary files /dev/null and b/public/bg/bg1_4.png differ diff --git a/public/bg/bg1_5.png b/public/bg/bg1_5.png new file mode 100644 index 0000000..76ef85a Binary files /dev/null and b/public/bg/bg1_5.png differ diff --git a/public/bg/bg1_6.png b/public/bg/bg1_6.png new file mode 100644 index 0000000..5a9243a Binary files /dev/null and b/public/bg/bg1_6.png differ diff --git a/public/bg/bg1_7.png b/public/bg/bg1_7.png new file mode 100644 index 0000000..8955f72 Binary files /dev/null and b/public/bg/bg1_7.png differ diff --git a/public/bg/bg1_8.png b/public/bg/bg1_8.png new file mode 100644 index 0000000..d4ac8b6 Binary files /dev/null and b/public/bg/bg1_8.png differ diff --git a/public/bg/bg1_9.png b/public/bg/bg1_9.png new file mode 100644 index 0000000..06b0ce6 Binary files /dev/null and b/public/bg/bg1_9.png differ diff --git a/public/bg/bg2_1.png b/public/bg/bg2_1.png new file mode 100644 index 0000000..34c905a Binary files /dev/null and b/public/bg/bg2_1.png differ diff --git a/public/bg/bg2_2.png b/public/bg/bg2_2.png new file mode 100644 index 0000000..d8e7167 Binary files /dev/null and b/public/bg/bg2_2.png differ diff --git a/public/bg/bg2_3.png b/public/bg/bg2_3.png new file mode 100644 index 0000000..a30cad9 Binary files /dev/null and b/public/bg/bg2_3.png differ diff --git a/public/bg/bg2_4.png b/public/bg/bg2_4.png new file mode 100644 index 0000000..dc933ab Binary files /dev/null and b/public/bg/bg2_4.png differ diff --git a/public/bg/bg2_5.png b/public/bg/bg2_5.png new file mode 100644 index 0000000..0f2ce43 Binary files /dev/null and b/public/bg/bg2_5.png differ diff --git a/public/bg/bg2_6.png b/public/bg/bg2_6.png new file mode 100644 index 0000000..f0ad132 Binary files /dev/null and b/public/bg/bg2_6.png differ diff --git a/public/bg/bg2_7.png b/public/bg/bg2_7.png new file mode 100644 index 0000000..a8f4cc2 Binary files /dev/null and b/public/bg/bg2_7.png differ diff --git a/public/bg/bg2_8.png b/public/bg/bg2_8.png new file mode 100644 index 0000000..eec9546 Binary files /dev/null and b/public/bg/bg2_8.png differ diff --git a/public/bg/bg3_1.png b/public/bg/bg3_1.png new file mode 100644 index 0000000..a768169 Binary files /dev/null and b/public/bg/bg3_1.png differ diff --git a/public/bg/bg3_12.png b/public/bg/bg3_12.png new file mode 100644 index 0000000..b411e7a Binary files /dev/null and b/public/bg/bg3_12.png differ diff --git a/public/bg/bg3_2.png b/public/bg/bg3_2.png new file mode 100644 index 0000000..23aa284 Binary files /dev/null and b/public/bg/bg3_2.png differ diff --git a/public/bg/bg3_3.png b/public/bg/bg3_3.png new file mode 100644 index 0000000..6dab6f9 Binary files /dev/null and b/public/bg/bg3_3.png differ diff --git a/public/bg/bg3_4.png b/public/bg/bg3_4.png new file mode 100644 index 0000000..0b54deb Binary files /dev/null and b/public/bg/bg3_4.png differ diff --git a/public/bg/bg3_5.png b/public/bg/bg3_5.png new file mode 100644 index 0000000..84794c0 Binary files /dev/null and b/public/bg/bg3_5.png differ diff --git a/public/bg/bg3_6.png b/public/bg/bg3_6.png new file mode 100644 index 0000000..c497108 Binary files /dev/null and b/public/bg/bg3_6.png differ diff --git a/public/body/1.png b/public/body/1.png index 83816c5..4ce9e71 100644 Binary files a/public/body/1.png and b/public/body/1.png differ diff --git a/public/body/10.png b/public/body/10.png new file mode 100644 index 0000000..5a4bc4a Binary files /dev/null and b/public/body/10.png differ diff --git a/public/body/11.png b/public/body/11.png new file mode 100644 index 0000000..a897a1d Binary files /dev/null and b/public/body/11.png differ diff --git a/public/body/12.png b/public/body/12.png new file mode 100644 index 0000000..353c0b8 Binary files /dev/null and b/public/body/12.png differ diff --git a/public/body/13.png b/public/body/13.png new file mode 100644 index 0000000..a134a89 Binary files /dev/null and b/public/body/13.png differ diff --git a/public/body/14.png b/public/body/14.png new file mode 100644 index 0000000..2143145 Binary files /dev/null and b/public/body/14.png differ diff --git a/public/body/15.png b/public/body/15.png new file mode 100644 index 0000000..4ac4e28 Binary files /dev/null and b/public/body/15.png differ diff --git a/public/body/16.png b/public/body/16.png new file mode 100644 index 0000000..c594ec9 Binary files /dev/null and b/public/body/16.png differ diff --git a/public/body/17.png b/public/body/17.png new file mode 100644 index 0000000..1d2cb0a Binary files /dev/null and b/public/body/17.png differ diff --git a/public/body/18.png b/public/body/18.png new file mode 100644 index 0000000..89ee8bd Binary files /dev/null and b/public/body/18.png differ diff --git a/public/body/19.png b/public/body/19.png new file mode 100644 index 0000000..f14a285 Binary files /dev/null and b/public/body/19.png differ diff --git a/public/body/2.png b/public/body/2.png index a6da3f8..f1873d4 100644 Binary files a/public/body/2.png and b/public/body/2.png differ diff --git a/public/body/20.png b/public/body/20.png new file mode 100644 index 0000000..7e50c58 Binary files /dev/null and b/public/body/20.png differ diff --git a/public/body/22.png b/public/body/22.png new file mode 100644 index 0000000..22e061c Binary files /dev/null and b/public/body/22.png differ diff --git a/public/body/3.png b/public/body/3.png index 3166cb2..7b6fa3d 100644 Binary files a/public/body/3.png and b/public/body/3.png differ diff --git a/public/body/4.png b/public/body/4.png index 5258d51..d409c25 100644 Binary files a/public/body/4.png and b/public/body/4.png differ diff --git a/public/body/5.png b/public/body/5.png index eb00793..5760603 100644 Binary files a/public/body/5.png and b/public/body/5.png differ diff --git a/public/body/6.png b/public/body/6.png index 9235ce0..9e0f3aa 100644 Binary files a/public/body/6.png and b/public/body/6.png differ diff --git a/public/body/7.png b/public/body/7.png index 8515e06..d27b330 100644 Binary files a/public/body/7.png and b/public/body/7.png differ diff --git a/public/body/8.png b/public/body/8.png index db419ea..e6857db 100644 Binary files a/public/body/8.png and b/public/body/8.png differ diff --git a/public/body/9.png b/public/body/9.png new file mode 100644 index 0000000..3bfe0ba Binary files /dev/null and b/public/body/9.png differ diff --git a/public/body/_1.png b/public/body/_1.png new file mode 100644 index 0000000..ff1ff95 Binary files /dev/null and b/public/body/_1.png differ diff --git a/public/head/1.png b/public/head/1.png index 3f06b44..eacf4af 100644 Binary files a/public/head/1.png and b/public/head/1.png differ diff --git a/public/head/10.png b/public/head/10.png new file mode 100644 index 0000000..43ce90a Binary files /dev/null and b/public/head/10.png differ diff --git a/public/head/11.png b/public/head/11.png new file mode 100644 index 0000000..2a968d1 Binary files /dev/null and b/public/head/11.png differ diff --git a/public/head/12.png b/public/head/12.png new file mode 100644 index 0000000..fd553f5 Binary files /dev/null and b/public/head/12.png differ diff --git a/public/head/13.png b/public/head/13.png new file mode 100644 index 0000000..b82a395 Binary files /dev/null and b/public/head/13.png differ diff --git a/public/head/14.png b/public/head/14.png new file mode 100644 index 0000000..97865e2 Binary files /dev/null and b/public/head/14.png differ diff --git a/public/head/15.png b/public/head/15.png new file mode 100644 index 0000000..cee51f5 Binary files /dev/null and b/public/head/15.png differ diff --git a/public/head/16.png b/public/head/16.png new file mode 100644 index 0000000..b21555b Binary files /dev/null and b/public/head/16.png differ diff --git a/public/head/17.png b/public/head/17.png new file mode 100644 index 0000000..a5a6d23 Binary files /dev/null and b/public/head/17.png differ diff --git a/public/head/18.png b/public/head/18.png new file mode 100644 index 0000000..34680b0 Binary files /dev/null and b/public/head/18.png differ diff --git a/public/head/19.png b/public/head/19.png new file mode 100644 index 0000000..0396676 Binary files /dev/null and b/public/head/19.png differ diff --git a/public/head/2.png b/public/head/2.png index a1a057d..3c1332a 100644 Binary files a/public/head/2.png and b/public/head/2.png differ diff --git a/public/head/20.png b/public/head/20.png new file mode 100644 index 0000000..9b4f328 Binary files /dev/null and b/public/head/20.png differ diff --git a/public/head/21.png b/public/head/21.png new file mode 100644 index 0000000..49338e7 Binary files /dev/null and b/public/head/21.png differ diff --git a/public/head/22.png b/public/head/22.png new file mode 100644 index 0000000..f9c7663 Binary files /dev/null and b/public/head/22.png differ diff --git a/public/head/3.png b/public/head/3.png index 73ed947..0a7c6dd 100644 Binary files a/public/head/3.png and b/public/head/3.png differ diff --git a/public/head/4.png b/public/head/4.png index 310f677..0872de8 100644 Binary files a/public/head/4.png and b/public/head/4.png differ diff --git a/public/head/5.png b/public/head/5.png index 4bc9ff3..372be16 100644 Binary files a/public/head/5.png and b/public/head/5.png differ diff --git a/public/head/6.png b/public/head/6.png index 574b26e..9538275 100644 Binary files a/public/head/6.png and b/public/head/6.png differ diff --git a/public/head/7.png b/public/head/7.png index 18b36ed..f78f04c 100644 Binary files a/public/head/7.png and b/public/head/7.png differ diff --git a/public/head/8.png b/public/head/8.png index d6f5e39..e45df94 100644 Binary files a/public/head/8.png and b/public/head/8.png differ diff --git a/public/head/9.png b/public/head/9.png index 8cde163..292e3da 100644 Binary files a/public/head/9.png and b/public/head/9.png differ diff --git a/public/head/_1.png b/public/head/_1.png new file mode 100644 index 0000000..1cc2669 Binary files /dev/null and b/public/head/_1.png differ diff --git a/public/holes/1.png b/public/holes/1.png index dfa7149..5a2643c 100644 Binary files a/public/holes/1.png and b/public/holes/1.png differ diff --git a/public/index.html b/public/index.html index ddbbfce..7c21163 100644 --- a/public/index.html +++ b/public/index.html @@ -1,6 +1,7 @@
+ @@ -17,15 +18,15 @@ }) var stop = false - var x, y, width, minLen, maxLen, strokeW, margin, + var x, y, width, minLen, maxLen, strokeW, margin, buffer, angleDistanceMin, startPos, previousAng, strokeStyle, totalLength = 0, allLines = [], allColors = [], presetLines = [], presetColors = [], img, dropShadowColor, dropShadowLoop, dropShadowOffset, headOffset, headOffsets, tailOffset, tailOffsets, - totalHeads = 9, totalBodies = 8, totalTails = 7, totalBG = 3, totalPatterns = 8, + totalHeads = 8, totalBodies = 8, totalTails = 7, totalBG = 3, totalPatterns = 8, tails = [], heads = [], bodies = [], bgs = [], patterns = [], whichSegment, - head, tail, bgImg, makeMask, hole, - imagePath = "http://localhost:8888", + head, tail, bgImg, makeMask, hole, tweens, bgGradientColors, + imagePath = "", matchTail = true, firstSet = false @@ -61,17 +62,19 @@ } function setParams() { - width = 800 - maxLen = width / 12 + width = 686 + maxLen = 75 minLen = maxLen - strokeW = width / 12 //minLen / 1 - headWidth = strokeW * 1.8 + strokeW = 60//maxLen//width / 6 //minLen / 1 + headWidth = strokeW * 2.3 + margin = headWidth - maxNumberOfLines = 24 + maxNumberOfLines = 10 angleDistanceMin = 60 startPos = "random" // "bottom", "center", "random" strokeStyle = "random" // "randomGreen", "random", "gettingDarker", "none" - fps = 6 + fps = 50 + tweens = 10 bgColor = "rgb(226,226,226)" try { rotationMode = CENTER @@ -79,7 +82,7 @@ // console.log(e) } debug = false - animated = false + animated = true makeLoop = false keepRunning = true dropShadowColor = "rgba(0, 0, 0, 0.008)" @@ -93,22 +96,27 @@ startingY = false // width - margin startingAng = false //135 egg = false - bg = "image" // "solid", "gradient", "image" + bg = "image" // "solid", "gradient", "image", "fourGradient" dropShadowLoop = bg == "solid" ? 20 : 50 shouldSave = false taperEnd = false skipToEnd = false dontCross = false bodyOffset = Math.floor(Math.random() * totalBodies) - makeMask = true + makeMask = false dontClearBG = false preset = false sameSegment = true + headAsSegment = false // bodies = patterns // which Segment is random selection from allLines - whichSegment = Math.floor(random(0, bodies.length)) - + whichSegment = 0 + //Math.floor(random(0, bodies.length)) + if (bg == "fourGradient") { + bgGradientColors = [[randomNum(0, 255), randomNum(0, 255), randomNum(0, 255)], [randomNum(0, 255), randomNum(0, 255), randomNum(0, 255)], [randomNum(0, 255), randomNum(0, 255), randomNum(0, 255)], [randomNum(0, 255), randomNum(0, 255), randomNum(0, 255)]]; + } + buffer = -margin / 2//0 //- margin//width / 3 } function setup() { if (!firstSet) { @@ -129,12 +137,12 @@ headOffsets = { _1: { - xFactor: 1.8, - yFactor: 2.3 + xFactor: 2.5, + yFactor: 2.8 }, _2: { - xFactor: 10, - yFactor: 2.1 + xFactor: 2.5, + yFactor: 2.3 }, _3: { xFactor: 2.2, @@ -198,23 +206,32 @@ } } + var bgFamilies = [ + 9, // bg1 has 9 variations + 9, // bg2 has 9 variations + 3 + ] + function preload() { - var tailRandom = Math.ceil(Math.random() * totalTails) + + var tailRandom = 1//Math.ceil(Math.random() * totalTails) var headRandom; + console.log(imagePath + `/tail/${tailRandom}.png`) tail = loadImage(imagePath + `/tail/${tailRandom}.png`) - if (tailRandom < 7 && matchTail) { + + if (tailRandom < 6 && matchTail) { headRandom = tailRandom head = loadImage(imagePath + `/head/${tailRandom}.png`) } else { headRandom = totalTails + Math.floor(Math.random() * (totalHeads - totalTails + 1)) - console.log(headRandom) head = loadImage(imagePath + `/head/${headRandom}.png`) } headOffset = headOffsets.hasOwnProperty("_" + headRandom) ? headOffsets["_" + headRandom] : defaultHeadOffsets tailOffset = tailOffsets.hasOwnProperty("_" + tailRandom) ? tailOffsets["_" + tailRandom] : defaultTailOffsets - - bgImg = loadImage(imagePath + `/bg/${Math.ceil(Math.random() * totalBG)}.jpeg`) + var bgFamily = 3//Math.ceil(Math.random() * totalBG) + var specificBG = 1//Math.ceil(Math.random() * bgFamilies[bgFamily - 1]) + bgImg = loadImage(imagePath + `/bg/bg${bgFamily}_${specificBG}.png`) for (var i = 1; i <= totalBodies; i++) { bodies.push(loadImage(imagePath + `/body/${i}.png`)) @@ -222,9 +239,9 @@ // for (var i = 1; i <= totalBG; i++) { // bgs.push(loadImage(imagePath + `/bg/${i}.jpeg`)) // uses jpeg instead of png // } - for (var i = 1; i <= totalTails; i++) { - tails.push(loadImage(imagePath + `/tail/${i}.png`)) - } + // for (var i = 1; i <= totalTails; i++) { + // tails.push(loadImage(imagePath + `/tail/${i}.png`)) + // } for (var i = 1; i <= totalPatterns; i++) { patterns.push(loadImage(imagePath + `/pattern/${i}.jpg`)) // uses jpg } @@ -294,6 +311,25 @@ const X_AXIS = 2; let b1, b2, c1, c2; + var savedBG = false + function fourColorGradient(colors, resolution) { + if (!savedBG) { + savedBG = createGraphics(width, width) + for (let i = 0; i < resolution; i++) { + for (let j = 0; j < resolution; j++) { + let s = width / resolution; + let wx = i * s / width + let wy = j * s / width + savedBG.noStroke() + savedBG.fill(weightedAvgColor(weightedAvgColor(colors[0], colors[1], wx), weightedAvgColor(colors[3], colors[2], wx), wy)) + savedBG.rect(i * s, j * s, s, s) + } + } + } + + image(savedBG, width / 2, width / 2, width, width) + } + function setGradient(x, y, w, h, c1, c2, axis) { noFill(); @@ -321,6 +357,8 @@ addCartesian() } else if (bg == "solid") { background(bgColor); + } else if (bg == "fourGradient") { + fourColorGradient(bgGradientColors, width) } else if (bg == "gradient") { b1 = color(255); b2 = color(0); @@ -382,6 +420,7 @@ angleMode(DEGREES); } function addCartesian() { + background(bgColor); textSize(16); strokeWeight(3) @@ -396,29 +435,46 @@ strokeWeight(1) line(0, i, width, i) } - line(margin, margin, width - margin, margin) - line(width - margin, margin, width - margin, width) - line(width - margin, width, margin, width) - line(margin, width, margin, margin) - - // stroke("green") - // for (var i = 0; i < 12; i++) { - // var cardinalX = (width / 2) + Math.cos(((i * 30)) * Math.PI / 180) * 225 - // var cardinalY = (width / 2) + Math.sin(((i * 30)) * Math.PI / 180) * 225 - // strokeWeight(0) - // fill("green") - // text(i * 30, cardinalX, cardinalY) - // strokeWeight(1) - // line(width / 2, width / 2, cardinalX, cardinalY) + rectMode(CORNER) + strokeWeight(0) + fill('rgba(255,255,0,0.5)') + rect(0, 0, width, -buffer) + rect(0, -buffer, -buffer, width) + rect(width - -buffer, -buffer, -buffer, width) + rect(-buffer, width - -buffer, width - - buffer - - buffer, -buffer) - // } + rectMode(rotationMode) + strokeWeight(1) - // stroke("red") - // for (var i = 0; i < 8; i++) { - // var cardinalX = (width / 2) + Math.cos(((i * 45)) * Math.PI / 180) * 500 - // var cardinalY = (width / 2) + Math.sin(((i * 45)) * Math.PI / 180) * 500 - // line(width / 2, width / 2, cardinalX, cardinalY) - // } + + // line(margin, margin, width - margin, margin) + // line(width - margin, margin, width - margin, width) + // line(width - margin, width, margin, width) + // line(margin, width, margin, margin) + + + stroke("green") + for (var i = 0; i < 12; i++) { + var cardinalX = (width / 2) + Math.cos(((i * 30)) * Math.PI / 180) * 225 + var cardinalY = (width / 2) + Math.sin(((i * 30)) * Math.PI / 180) * 225 + strokeWeight(0) + fill("green") + text(i * 30, cardinalX, cardinalY) + strokeWeight(1) + line(width / 2, width / 2, cardinalX, cardinalY) + + } + + stroke("red") + fill("red") + for (var i = 0; i < 8; i++) { + var cardinalX = (width / 2) + Math.cos(((i * 45)) * Math.PI / 180) * (width / 2.5) + var cardinalY = (width / 2) + Math.sin(((i * 45)) * Math.PI / 180) * (width / 2.5) + strokeWeight(1) + line(width / 2, width / 2, cardinalX, cardinalY) + strokeWeight(0) + text(i * (360 / 8), cardinalX, cardinalY) + } } @@ -428,7 +484,7 @@ if (stop) return totalLength++ if (!keepRunning) { - if (totalLength > (maxNumberOfLines * (animated ? 2 : 1))) { + if (totalLength > (maxNumberOfLines * (animated ? tweens : 1))) { if (makeLoop) { totalLength = 0 allLines = [] @@ -454,38 +510,18 @@ } } - // if totalLength is odd - // if (totalLength % 2 || !animated) { - addLine() - // if (animated && !drawings) { - // drawMidLines() - // } - // } else { - // drawLines() - // } - if (totalLength != (maxNumberOfLines * (animated ? 2 : 1)) && skipToEnd) { - return + if ((totalLength % tweens == 1) || !animated) { + addLine() } + if (!dontClearBG) { addBackground() } - - if (!animated) { - if (!drawings) { - drawLines() - } else { - // drawLines() - if (debug) { - drawDebug() - } - drawImgs() - // drawLines() - - } - } - // shouldSave image - + // if (debug) { + // drawDebug() + // } + drawSegments() } function setStrokeColor() { var c @@ -600,12 +636,15 @@ // arc(l.x1, l.y1, 40, 40, l.ang - angleDistanceMin, l.ang + angleDistanceMin); } catch (e) { } - stroke("red") - strokeWeight(4) + stroke("black") + var debugLineWeight = width / 40 + strokeWeight(debugLineWeight) line(l.x1, l.y1, l.x2, l.y2) - strokeWeight(10) - stroke('red') + strokeWeight(width / 40) + // stroke('rgb(0,255,0)') + stroke('green') point(l.x1, l.y1) + point(l.x2, l.y2) stroke('blue') strokeWeight(0) fill("blue") @@ -616,52 +655,93 @@ previewX = l.failed[j].newX previewY = l.failed[j].newY stroke(l.failed[j].randomColor) - strokeWeight(4) + strokeWeight(debugLineWeight) line(l.x1, l.y1, previewX, previewY) strokeWeight(0) fill("blue") halfX = l.x1 > previewX ? l.x1 - ((l.x1 - previewX) / 2) : previewX - ((previewX - l.x1) / 2) halfY = l.y1 > previewY ? l.y1 - ((l.y1 - previewY) / 2) : previewY - ((previewY - l.y1) / 2) text(j + 1, halfX + 5, halfY); + strokeWeight(width / 40) + stroke("red") + point(previewX, previewY) } try { strokeWeight(0) - fill("rgba(0,0,255,0.4)") - arc(l.x2, l.y2, 40, 40, l.ang - angleDistanceMin, l.ang + angleDistanceMin); + // fill("rgba(0,0,255,0.4)") + // fill('green') + arc(l.x2, l.y2, maxLen * 2, maxLen * 2, l.ang - angleDistanceMin, l.ang + angleDistanceMin); } catch (e) { } } } - function drawImgs() { + // function dist(x1, y1, x2, y2) { + // return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) + // } + + var renderedBodies = {} + + function drawSegments() { for (var i = 0; i < allLines.length; i++) { + if (i == 0 && allLines.length > maxNumberOfLines) { + continue + } // start new relative translation and rotation var l = allLines[i] - if (includeShadow) { - addDropShadow(i, allLines) + var c = allColors[i] + + if (animated) { + var offsetTilNextSegment = totalLength % tweens + if (i == 0 && allLines.length <= maxNumberOfLines) { + lastLine = { + x1: startingX, + y1: startingY, + x2: startingX, + y2: startingY + } + } else { + lastLine = allLines[i - 1] + } + + // console.log('lastLine') + // console.log(`ll.x1: ${lastLine.x1}, ll.y1: ${lastLine.y1}, ll.x2: ${lastLine.x2}, ll.y2: ${lastLine.y2}`) + + // normally we draw each line x1,y1 to x2,y2 + // x1,y1 is the end of the previous line + // x2,y2 is the end of the current line + x1 = offsetTilNextSegment == 0 ? l.x1 : ((l.x1 - lastLine.x1) * (offsetTilNextSegment / tweens)) + lastLine.x1 + y1 = offsetTilNextSegment == 0 ? l.y1 : ((l.y1 - lastLine.y1) * (offsetTilNextSegment / tweens)) + lastLine.y1 + x2 = offsetTilNextSegment == 0 ? l.x2 : ((l.x2 - lastLine.x2) * (offsetTilNextSegment / tweens)) + lastLine.x2 + y2 = offsetTilNextSegment == 0 ? l.y2 : ((l.y2 - lastLine.y2) * (offsetTilNextSegment / tweens)) + lastLine.y2 + + // len is the distance between x1,y1 and x2,y2 + len = dist(x1, y1, x2, y2) + ang = Math.atan2(y2 - y1, x2 - x1) * 180 / Math.PI; + + + // console.log(`tween line # ${offsetTilNextSegment} of ${tweens}`) + // console.log(`x1: ${x1}, y1: ${y1}, x2: ${x2}, y2: ${y2}`) + // point(x1, y1) + // point(x2, y2) + + // if (i == allLines.length - 1) { + // x1 = x + // y1 = y + // } + } else { + x1 = l.x1 + x2 = l.x2 + y1 = l.y1 + y2 = l.y2 + len = l.len + ang = l.ang } - // get the index of the item in allLines as the opposite of the position in the array - var index = allLines.length - i - 1 - whichSegment = sameSegment ? whichSegment : (index + bodyOffset) % bodies.length - pic = bodies[whichSegment] - var flip = index % 4 - switch (flip) { - case 0: - flip1 = true - flip2 = true - break; - case 1: - flip1 = false - flip2 = true - break; - case 2: - flip1 = true - flip2 = false - break; - case 3: - flip1 = false - flip2 = false - break; + + + + if (includeShadow) { + addDropShadow(i, allLines) } if (taperEnd) { @@ -676,115 +756,216 @@ currentWidth = strokeW } - if (i == 0 && !debug) { + var a = (i == 0 && !debug && !animated) + var b = (i == 0 && !debug && animated) || (i == 1 && totalLength > ((maxNumberOfLines) * tweens) && !debug && animated) + if (a || b) { // draw the hole - var holeWidth = currentWidth * 2.5 - image(hole, startingX - (currentWidth / 8), startingY - (currentWidth / 4), holeWidth, holeWidth); + var holeWidth = currentWidth * 3 + // push() + // tint(255, 127) + image(hole, startingX - (currentWidth / 8), startingY - (currentWidth / 4), holeWidth, holeWidth); + // pop() } - if (!debug) { - - var imagePattern - if (makeMask) { - var strokeMask = createGraphics(l.len + (currentWidth * 2), currentWidth); - strokeMask.strokeWeight(currentWidth) - strokeMask.line(currentWidth / 2, currentWidth / 2, l.len + (currentWidth * 1.5), currentWidth / 2) - - imagePattern = createGraphics(l.len + (currentWidth * 2), currentWidth); - imagePattern.background(allColors[i]) - // imagePattern.image(pic, 0, 0, l.len + (currentWidth * 2), currentWidth) - imagePattern.image(pic, 0, -currentWidth / 2, l.len + (currentWidth * 2), currentWidth * 2) - - imagePattern.loadPixels() - strokeMask.loadPixels() - for (let j = 0; j < imagePattern.pixels.length; j += 4) { - imagePattern.pixels[j + 3] = strokeMask.pixels[j + 3] + if (i !== allLines.length - 1 || !headAsSegment) { + if (drawings && !debug) { + + // get the index of the item in allLines as the opposite of the position in the array + var index = allLines.length - i - 1 + whichSegment = sameSegment ? whichSegment : (index + bodyOffset) % bodies.length + pic = bodies[whichSegment] + var flip1 = (x1 - x2) > (width / 80) + var flip2 = flip1 + + if (!debug) { + + var imagePattern + if (makeMask) { + var renderedID = whichSegment + if (!renderedBodies[renderedID]) { + var strokeMask = createGraphics(len + (currentWidth * 2), currentWidth); + strokeMask.strokeWeight(currentWidth) + strokeMask.line(currentWidth / 2, currentWidth / 2, len + (currentWidth * 1.5), currentWidth / 2) + + + imagePattern = createGraphics(len + (currentWidth * 2), currentWidth); + imagePattern.background(c) + // imagePattern.image(pic, 0, 0, len + (currentWidth * 2), currentWidth) + imagePattern.image(pic, 0, -currentWidth / 2, len + (currentWidth * 2), currentWidth * 2) + + imagePattern.loadPixels() + strokeMask.loadPixels() + for (let j = 0; j < imagePattern.pixels.length; j += 4) { + imagePattern.pixels[j + 3] = strokeMask.pixels[j + 3] + } + imagePattern.updatePixels() + // console.log({ l }) + renderedBodies[renderedID] = imagePattern + // l.maskedImage = imagePattern + // allLines[i].maskedImage = imagePattern + // console.log({ l }) + } else { + imagePattern = renderedBodies[renderedID] + } + } else { + imagePattern = pic + } + + push() + var xDist = Math.abs(x2 - x1) + var yDist = Math.abs(y2 - y1) + var fractionOfTotal = 1 / 2 + var p = { + x: x1 + ((x2 < x1 ? -1 : 1) * xDist) * fractionOfTotal, + y: y1 + ((y2 < y1 ? -1 : 1) * yDist) * fractionOfTotal + } + translate(p.x, p.y); + rotate(ang) + + push() + scale(flip1 ? -1 : 1, flip2 ? -1 : 1) + // tint(segColor) + // tint(c[0], c[1], c[2]) + var segmentWeight, addToLength + if (makeMask) { + segmentWeight = currentWidth / 1.75 // strokeW - ((allLines.length - 1 - i) * diff) + stroke("black") + strokeWeight(segmentWeight + (segmentWeight * 0.1)) + line(-len / 2, 0, len / 2, 0) + addToLength = segmentWeight + } else { + segmentWeight = currentWidth / 1.2 + addToLength = segmentWeight / 2 + } + console.log(`len is ${ len} segment is ${len + addToLength} x ${segmentWeight} pixels`) + image(imagePattern, 0, 0, len + addToLength, segmentWeight); + pop() + + + // revert to original translation and rotation + pop() } - imagePattern.updatePixels() - } else { - imagePattern = pic - } - - push() - var xDist = Math.abs(l.x2 - l.x1) - var yDist = Math.abs(l.y2 - l.y1) - var fractionOfTotal = 1 / 2 - var p = { - x: l.x1 + ((l.x2 < l.x1 ? -1 : 1) * xDist) * fractionOfTotal, - y: l.y1 + ((l.y2 < l.y1 ? -1 : 1) * yDist) * fractionOfTotal - } - translate(p.x, p.y); - rotate(l.ang) - - push() - scale(flip1 ? -1 : 1, flip2 ? -1 : 1) - // tint(segColor) - // tint(allColors[i][0], allColors[i][1], allColors[i][2]) - var segmentWeight, addToLength - if (makeMask) { - segmentWeight = currentWidth / 1.75 // strokeW - ((allLines.length - 1 - i) * diff) + } else if (debug) { stroke("black") - strokeWeight(segmentWeight + (segmentWeight * 0.1)) - line(-l.len / 2, 0, l.len / 2, 0) - addToLength = segmentWeight + var debugLineWeight = width / 50 + + strokeWeight(debugLineWeight) + line(x1, y1, x2, y2) + strokeWeight(debugLineWeight) + stroke('rgb(0,255,0)') + point(x1, y1) + point(x2, y2) + stroke('blue') + strokeWeight(0) + fill("blue") + text(`${Math.floor(x1)}, ${Math.floor(y1)} `, x1 + 5, y1 - 5) + + + for (var j = 0; j < l.failed.length; j++) { + previewX = l.failed[j].newX + previewY = l.failed[j].newY + stroke(l.failed[j].randomColor) + strokeWeight(debugLineWeight) + line(x1, y1, previewX, previewY) + strokeWeight(0) + fill("blue") + halfX = x1 > previewX ? x1 - ((x1 - previewX) / 2) : previewX - ((previewX - x1) / 2) + halfY = y1 > previewY ? y1 - ((y1 - previewY) / 2) : previewY - ((previewY - y1) / 2) + text(j + 1, halfX + 5, halfY); + strokeWeight(debugLineWeight) + stroke("red") + point(previewX, previewY) + } + try { + strokeWeight(0) + fill("rgba(0,0,255,0.4)") + arc(x2, y2, maxLen, maxLen, ang - angleDistanceMin, ang + angleDistanceMin); + } catch (e) { } } else { - segmentWeight = currentWidth / 1.2 - addToLength = segmentWeight / 2 + stroke("black") + var segmentWeight = strokeW / 1.75 // strokeW - ((allLines.length - 1 - i) * diff) + strokeWeight(segmentWeight + 2) + line(x1, y1, x2, y2) + stroke(c) + strokeWeight(segmentWeight) + line(x1, y1, x2, y2) } - image(imagePattern, 0, 0, l.len + addToLength, segmentWeight); - pop() + } + + var tailLength = currentWidth * 2.3 + var tailWidth = tailLength / 2 + var calcTailOffset = { + x: tailLength / tailOffset.xFactor, + y: tailWidth * tailOffset.yFactor + } + // draw the tail + var a = i == 0 && keepRunning && (totalLength > maxNumberOfLines) && !animated + var b = i == 1 && keepRunning && (totalLength > ((maxNumberOfLines + 1) * tweens)) && animated + // console.log({ i, keepRunning, totalLength, maxNumberOfLines, tweens }) + // console.log({ a, b }) + if ((a) || (b)) { + if ((x1 - x2) > (width / 80)) { + // if (x2 < x1) {//} && (x1 - x2) > margin) { + push() + scale(-1, 1) + var tailX = -x1 - calcTailOffset.x + var tailY = y1 - calcTailOffset.y + image(tail, tailX, tailY, tailLength, tailWidth); + pop() + } else { - // revert to original translation and rotation - pop() + var tailX = x1 - calcTailOffset.x + var tailY = y1 - calcTailOffset.y + image(tail, tailX, tailY, tailLength, tailWidth); + } } + // draw the head if (i == allLines.length - 1) { // stroke("rgba(255,0,0,0.1)") noStroke() - fill("rgba(255,0,0,0.1)") + fill("rgba(255,0,0,0.5)") // var headOffset = { // xFactor: 2, // yFactor: 2.5 // } - var calcHeadOffset = { - x: headWidth / headOffset.xFactor, - y: headWidth / headOffset.yFactor - } - if (l.x2 < l.x1) {//} && (l.x1 - l.x2) > margin) { + if (headAsSegment) { push() - scale(-1, 1) - // rect((-l.x2) + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth) - image(head, (-l.x2) + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth, headWidth); + rectMode(CORNER); + imageMode(CORNER); + translate(x1, y1) + rotate(ang) + if ((x1 - x2) > (width / 80)) { // changes to left direction by minimum amount + scale(1, -1) + } + headX = -5 + headY = 5 + image(head, headX, headY, headWidth, -headWidth) pop() + rectMode(rotationMode); + imageMode(rotationMode); } else { - // rect(l.x2 + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth) - image(head, l.x2 + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth, headWidth); + var calcHeadOffset = { + x: headWidth / headOffset.xFactor, + y: headWidth / headOffset.yFactor + } + if ((l.x1 - l.x2) > (width / 80)) { + push() + scale(-1, 1) + // rect((-l.x2) + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth) + image(head, (-x2) + calcHeadOffset.x, y2 - calcHeadOffset.y, headWidth, headWidth); + pop() + } else { + // rect(l.x2 + calcHeadOffset.x, l.y2 - calcHeadOffset.y, headWidth) + image(head, x2 + calcHeadOffset.x, y2 - calcHeadOffset.y, headWidth, headWidth); + } } - } - var tailLength = currentWidth * 1.4 - var tailWidth = tailLength / 2 - var calcTailOffset = { - x: tailLength / tailOffset.xFactor, - y: tailWidth * tailOffset.yFactor - } - - // draw the tail - if (i == 0 && keepRunning && allLines.length >= maxNumberOfLines) { - - if (l.x2 < l.x1) {//} && (l.x1 - l.x2) > margin) { - push() - scale(-1, 1) - image(tail, -l.x1 - calcTailOffset.x, l.y1 - calcTailOffset.y, tailLength, tailWidth); - pop() - } else { - image(tail, l.x1 - calcTailOffset.x, l.y1 - calcTailOffset.y, tailLength, tailWidth); - } } // // draw the shaddow on the entrance of the egg @@ -799,58 +980,35 @@ } } - function drawMidLines() { - for (var i = 0; i < allLines.length; i++) { - var x1, y1, x2, y2 - var l = allLines[i] - if (i == 0) { - x1 = l.x1 - y1 = l.y1 - x2 = (l.x1 + l.x2) / 2 - y2 = (l.y1 + l.y2) / 2 - } else { - var prevL = allLines[i - 1] - x1 = (prevL.x1 + prevL.x2) / 2 - y1 = (prevL.y1 + prevL.y2) / 2 - - x2 = (l.x1 + l.x2) / 2 - y2 = (l.y1 + l.y2) / 2 - } - var c = allColors[i] - stroke("rgba(0, 0, 0, 1)") - strokeWeight(strokeW + 2) - line(x1, y1, x2, y2) - if (!debug) { - // stroke(c) - // strokeWeight(strokeW) - // line(x1, y1, x2, y2) - } - - } - } - - function drawLines() { - // var diff = Math.floor(strokeW / allLines.length) - - for (var i = 0; i < allLines.length; i++) { - var l = allLines[i] - var c = allColors[i] - if (!debug && includeShadow) { - addDropShadow(i, allLines) - } - stroke("black") - // make segmentWeight a fraction of the length of allLines - - var segmentWeight = strokeW / 1.75 // strokeW - ((allLines.length - 1 - i) * diff) - strokeWeight(segmentWeight + 2) - line(l.x1, l.y1, l.x2, l.y2) - if (!debug) { - stroke(c) - strokeWeight(segmentWeight) - line(l.x1, l.y1, l.x2, l.y2) - } - } - } + // function drawMidLines() { + // for (var i = 0; i < allLines.length; i++) { + // var x1, y1, x2, y2 + // var l = allLines[i] + // if (i == 0) { + // x1 = l.x1 + // y1 = l.y1 + // x2 = (l.x1 + l.x2) / 2 + // y2 = (l.y1 + l.y2) / 2 + // } else { + // var prevL = allLines[i - 1] + // x1 = (prevL.x1 + prevL.x2) / 2 + // y1 = (prevL.y1 + prevL.y2) / 2 + + // x2 = (l.x1 + l.x2) / 2 + // y2 = (l.y1 + l.y2) / 2 + // } + // var c = allColors[i] + // stroke("rgba(0, 0, 0, 1)") + // strokeWeight(strokeW + 2) + // line(x1, y1, x2, y2) + // if (!debug) { + // // stroke(c) + // // strokeWeight(strokeW) + // // line(x1, y1, x2, y2) + // } + + // } + // } function addLine() { @@ -864,14 +1022,13 @@ previousAng = Math.floor(Math.random() * 360) } var len = pickLength() - var angResults = returnNextPoint(x, y, previousAng, angleDistanceMin, len, width, margin) + var angResults = wander(x, y, previousAng, angleDistanceMin, len, width, margin) var ang = angResults.angle - // var ang = pickAngle(x, y, angleDistanceMin) + x2 = x + Math.cos(ang * Math.PI / 180) * len y2 = y + Math.sin(ang * Math.PI / 180) * len c = setStrokeColor() - var newLine = { x1: x, y1: y, @@ -879,12 +1036,15 @@ y2: y2, ang: ang, len: len, - failed: angResults.failed + failed: angResults.failed, + maskedImage: false } allLines.push(newLine) allColors.unshift(c) - if (allLines.length > maxNumberOfLines) { + var addToMax = animated ? 1 : 0 + + if (allLines.length > maxNumberOfLines + addToMax) { allLines.shift() allColors.shift() } @@ -895,7 +1055,7 @@ } function pickLength() { - return Math.ceil(random(minLen - 1, maxLen)) + return Math.ceil(random(minLen , maxLen)) } @@ -917,80 +1077,14 @@ } }; - // pickAngle - /* - The pickAngle function is the heart of the algorithm. - It takes the current x and y coordinates and returns an angle that is within the angleDistanceMin of the previous angle. - It then checks whether this new angle is within the bounds of the canvas. - If it is not, it will try to find an angle that is within the bounds of the canvas. - It does this by adding increments to the new angle until it reaches the angleDistanceMin. - If it still can't find an angle it will repeat the process, only this time removing increments from the new angle. - If this still doesn't work it will try increasing the angleDistanceMin and doing both adding and removing again. - If this still doens't work it will continue to increase the angleDistanceMin and repeat the attempts until angleDistanceMin is 180. - If it still does not find a working angle by then it will throw an Error and print the coordinates that it was unable to succeed from. - */ - - - function testAlgo() { - totalTries = 0 - totalFailures = 0 - attempts = 1_000_000 - var testWidth = 800 - var testLineLength = testWidth / 10 - var testMargin = (testWidth / 10) * 1.55 - - var testStartingX = testWidth - testMargin - var testStartingY = testWidth - testMargin - var testPreviousAngle = 45 - - var maxTries = 0 - var testMaxDifferenceBetweenAngles = 30 - for (var i = 0; i < attempts; i++) { - testStartingX = Math.floor(Math.random() * (testWidth - (testMargin * 2))) + testMargin - testStartingY = Math.floor(Math.random() * (testWidth - (testMargin * 2))) + testMargin - testPreviousAngle = Math.floor(Math.random() * 360) - try { - var results = returnNextPoint(testStartingX, testStartingY, testPreviousAngle, testMaxDifferenceBetweenAngles, testLineLength, testWidth, testMargin) - totalTries += results.tries - if (results.tries > maxTries) maxTries = results.tries - } catch (e) { - totalFailures += 1 - } - } - console.log(`----new algo-----`) - console.log(`Max tries: ${maxTries}`) - console.log(`Average tries: ${totalTries / attempts}`) - console.log(`Failures: ${totalFailures} (${Math.floor((totalFailures / attempts) * 100)}%)`) - } - - function testOld() { - var maxTries = 0 - var totalTries = 0 - var totalFailures = 0 - var attempts = 1_000_000 - for (var i = 0; i < attempts; i++) { - firstSet = false - setup() - previousAng = Math.floor(Math.random() * 360) - try { - var results = pickAngle(x, y, angleDistanceMin) - totalTries += results.attempts - if (results.attempts > maxTries) maxTries = results.attempts - } catch (e) { - console.log({ e }) - totalFailures += 1 - } - } - console.log(`----old algo-----`) - console.log(`Max tries: ${maxTries}`) - console.log(`Average tries: ${totalTries / attempts}`) - console.log(`Failures: ${totalFailures} (${Math.floor((totalFailures / attempts) * 100)}%)`) - } - // testOld() - // testAlgo() - - function returnNextPoint(previousX, previousY, previousAngle, maxDifferenceBetweenAngles, lineLength, width, margin) { + // wander is the heart of the algorithm + // it takes the previous line's end point and angle and returns a new angle + // the new angle is within the maxDifferenceBetweenAngles of the previous angle + // the new angle is also within the margin of the canvas + // if the new angle doesn't work, it tries again, increasing until the worst case scenario which is 180 degrees + // it's been optimized to find a solution 100% of the time in under + function wander(previousX, previousY, previousAngle, maxDifferenceBetweenAngles, lineLength, width, margin) { // maxDifferenceBetweenAngles cannot be greater than 180 if (maxDifferenceBetweenAngles > 180) throw new Error('maxDifferenceBetweenAngles cannot be greater than 180') @@ -1013,7 +1107,7 @@ // keeping track of the failed attempts allows you to debug var failed = [] // changeByAmount is the amount that the angle will be changed by each time. It should remain lower than maxDifferenceBetweenAngles - var changeByAmount = maxDifferenceBetweenAngles - 1 + var changeByAmount = 45//(maxDifferenceBetweenAngles) - 1 var anglesInACircle = 360 for (var i = 0; i < anglesInACircle / changeByAmount; i++) { // first try, i == 0 so isOdd is false @@ -1026,7 +1120,7 @@ // second try, addOrRemove should be -1 // third try, addOrRemove should be 1 // fourth try, addOrRemove should be -1 - var addOrRemove = (iIsOdd ? -1 : 1) + var addOrRemove = iIsOdd ? -1 : 1 // first try, i == 0 and timesTried should be 0 // second try, i == 1 and timesTried should be 1 @@ -1051,7 +1145,7 @@ if (!outSideCanvas(newX, newY, width, margin)) { return { x: newX, y: newY, tries: i + 1, angle: newAngle, failed } } - var randomColor = `rgb(${Math.ceil(random(0, 255))}, ${Math.ceil(random(0, 255))}, ${Math.ceil(random(0, 255))})` + var randomColor = `rgb(${Math.ceil(randomNum(0, 255))}, ${Math.ceil(randomNum(0, 255))}, ${Math.ceil(randomNum(0, 255))})` failed.push({ changeBy, newAngle, newX, newY, randomColor }) } console.log({ previousX, previousY, previousAngle, maxDifferenceBetweenAngles, lineLength, width, margin }) @@ -1060,246 +1154,89 @@ } function outSideCanvas(x, y, width, margin) { - if (x < margin || x > width - margin || y < margin || y > width) {//- margin) { + // if (x < 0 || x > width || y < 0 || y > width) {//- margin) { + // if (x < (margin / 2) || x > width - (margin / 2) || y < margin || y > width) {//- margin) { + if (x < 0 - buffer || x > width + buffer || y < 0 - buffer || y > width + buffer) {//- margin) { return true } return false } - function random(min, max) { - return Math.floor(Math.random() * (max - min + 1)) + min - } - - - function pickAngle(x1, y1, _angleDistanceMin) { - var attempts = 0 - if (isNaN(_angleDistanceMin)) { - _angleDistanceMin = 0 - } else if (_angleDistanceMin > 180) { - _angleDistanceMin = 180 - } - var startingAngle - if (previousAng) { - var delta = Math.ceil(random(-1 * _angleDistanceMin, _angleDistanceMin)) - if (debug) { - console.log({ x1, y1, previousAng, _angleDistanceMin, delta }) - } - var startingAngle = previousAng + delta - startingAngle = startingAngle < 0 ? 360 + startingAngle : (startingAngle > 360 ? startingAngle % 360 : startingAngle) - if (debug) { - try { - strokeWeight(0) - fill("rgba(0,0,255,0.2)") - arc(x1, y1, 40, 40, previousAng - _angleDistanceMin, previousAng + _angleDistanceMin); - } catch (e) { } - } - try { - fill("black") - } catch (e) { } - - } else { - startingAngle = Math.ceil(random(0, 360)) - // startingAngle = Math.ceil(random(0, 12)) * 30 + function testAlgo() { + totalTries = 0 + totalFailures = 0 + attempts = 1_000_000 + var testWidth = 800 + var testLineLength = testWidth / 10 + var testMargin = (testWidth / 10) * 1.55 - } + var testStartingX = testWidth - testMargin + var testStartingY = testWidth - testMargin + var testPreviousAngle = 45 - // try to find an angle that is not too close to the previous one - var foundAng = false + var maxTries = 0 + var tries = {} - // if the eventual angle (ang) is unacceptable, we will attempt to increase or decrease - // the ang until an acceptable one is found - // increaseLoop determines whether we increase or decrease and has a 50/50 chance of being true or false - var increaseLoop = startingAngle > 180 - if (debug) { - var strokeColor = `rgb(${Math.ceil(random(0, 255))}, ${Math.ceil(random(0, 255))}, ${Math.ceil(random(0, 255))})` - } - let loopThroughResults1 = loopThroughAngles(x1, y1, previousAng, startingAngle, increaseLoop, _angleDistanceMin, strokeColor) - attempts += loopThroughResults1.attempts - if (debug) { - console.log(`loopThroughResults1 ${loopThroughResults1.foundAng ? 'succeeded' : 'failed'}(ang = ${loopThroughResults1.ang})`) - } - if (!loopThroughResults1.foundAng) { - increaseLoop = !increaseLoop - loopThroughResults2 = loopThroughAngles(x1, y1, previousAng, startingAngle, increaseLoop, _angleDistanceMin, strokeColor) - attempts += loopThroughResults2.attempts - if (debug) { - console.log(`loopThroughResults2 ${loopThroughResults2.foundAng ? 'succeeded' : 'failed'}(ang = ${loopThroughResults2.ang})`) + var testMaxDifferenceBetweenAngles = 30 + for (var i = 0; i < attempts; i++) { + testStartingX = Math.floor(Math.random() * (testWidth - (testMargin * 2))) + testMargin + testStartingY = Math.floor(Math.random() * (testWidth - (testMargin * 2))) + testMargin + testPreviousAngle = Math.floor(Math.random() * 360) + try { + var results = wander(testStartingX, testStartingY, testPreviousAngle, testMaxDifferenceBetweenAngles, testLineLength, testWidth, testMargin) + totalTries += results.tries + tries[results.tries] = tries[results.tries] ? tries[results.tries] + 1 : 1 + if (results.tries > maxTries) maxTries = results.tries + } catch (e) { + totalFailures += 1 } - ang = loopThroughResults2.ang - foundAng = loopThroughResults2.foundAng - } else { - ang = loopThroughResults1.ang - foundAng = loopThroughResults1.foundAng } - - if (!foundAng) { - if (parseInt(_angleDistanceMin) >= 180) { - console.log({ x, y, previousAng }) - makeLoop = false - throw new Error('INCREASED TO MAX AND STILL NO SUITABLE ANG') - } else { - // incrementBy should be increased maximum 3 times and on the last time equal 180 regardless of original angleDistanceMin - var incrementBy = (180 - angleDistanceMin) / 3 - var results = pickAngle(x1, y1, (parseInt(_angleDistanceMin) + (incrementBy))) - ang = results.ang - attempts += results.attempts + // get the median + var modeMax = 0 + var mode = 0 + for (var key in tries) { + if (tries[key] > modeMax) { + modeMax = tries[key] + mode = key } } - return { ang, attempts } + console.log(`----new algo-----`) + console.log(`Max tries: ${maxTries}`) + console.log(`Average tries: ${totalTries / attempts}`) + console.log(`Mode: ${mode} (${tries[mode]} times)`) + console.log(`Failures: ${totalFailures} (${Math.floor((totalFailures / attempts) * 100)}%)`) } + // testAlgo() - function loopThroughAngles(x1, y1, previousAng, startingAngle, increaseLoop, _angleDistanceMin, strokeColor) { - - var attempts = 0 - var ang - var foundAng = false - var k = 0 - var incrementBy = 33 - var breakIntoNumberOfChunks = 6 - - var incrementUntil = 180 - // if prevoiusAng exists - if (!isNaN(previousAng)) { - - if (increaseLoop) { - _fromAngle = startingAngle - _toAngle = previousAng + _angleDistanceMin - // incrementUntil = getAngleDifference(startingAngle, previousAng + _angleDistanceMin) - } else { - _fromAngle = previousAng - _angleDistanceMin - _toAngle = startingAngle - // incrementUntil = getAngleDifference(previousAng - _angleDistanceMin, startingAngle) - } - if (_toAngle > _fromAngle) { - incrementUntil = _toAngle - _fromAngle - } else { - incrementUntil = getAngleDifference(_fromAngle, _toAngle) - } + function randomNum(min, max) { + return Math.floor(Math.random() * (max - min + 1)) + min + } - if (debug) { - console.log(`angleDifference between ${_fromAngle} and ${_toAngle} is ${incrementUntil}`) - } - incrementBy = Math.ceil(incrementUntil / breakIntoNumberOfChunks) - if (debug) { - console.log(`when ${increaseLoop ? 'incrementing, add' : 'decrementing, remove'} ${incrementBy} to / from ${startingAngle} until ${incrementUntil} have been ${increaseLoop ? 'added' : 'removed'}} `) - } - } else { - if (debug) { - console.log(`first angle attempt is ${startingAngle} `) - } + function weightedAvgColor(a, b, w) { + let x, y, z; + w = w + (w - 0.5) * 0.45; // Messed with the weight to get the color densities to match the image https://stackoverflow.com/questions/11482349/four-point-gradient-in-ios + if (w > 1) w = 0.99; + if (a[0] != b[0]) { + x = a[0] + (b[0] - a[0]) * w; } - - for (var i = 0; i < incrementUntil; i += incrementBy) { - attempts++ - k++ - if (k > breakIntoNumberOfChunks) { - console.log({ k }) - throw new Error("too many attempts") - } - if (increaseLoop) { - ang = (startingAngle + i) % 360 - } else { - ang = (startingAngle - i) - if (ang < 0) { - ang = 360 + ang - } - } - - // get the new position assuming maxLen is used - var previewX = x1 + Math.cos(ang * Math.PI / 180) * (maxLen) - var previewY = y1 + Math.sin(ang * Math.PI / 180) * (maxLen) - if (dontCross) { - var intersectsWithAnyOtherLine = false - for (var j = 0; j < allLines.length; j++) { - var curLine = allLines[j] - - var intersect = intersects(x, y, previewX, previewY, curLine.x1, curLine.y1, curLine.x2, curLine.y2) - - if (intersect) { - intersectsWithAnyOtherLine = true - // break out of the j makeLoop - break - } - } - if (intersectsWithAnyOtherLine) { - if (debug) { - console.log(`intersectsWithAnyOtherLine ${intersectsWithAnyOtherLine} at ${ang} `) - } - continue - } - } - - if (debug) { - console.log(`attempt ang ${ang} by changing by ${i} `) - strokeWeight(5) - stroke('red') - point(x1, y1) - stroke('blue') - strokeWeight(0) - fill("blue") - text(`${Math.floor(x1)}, ${Math.floor(y1)} `, x1 + 5, y1 - 5) - stroke(strokeColor) - strokeWeight(2) - line(x1, y1, previewX, previewY) - strokeWeight(0) - fill("blue") - halfX = x1 > previewX ? x1 - ((x1 - previewX) / 2) : previewX - ((previewX - x1) / 2) - halfY = y1 > previewY ? y1 - ((y1 - previewY) / 2) : previewY - ((previewY - y1) / 2) - text(k, halfX, halfY); - } - // if the new position is outside the canvas plus some margin, skip this angle - if ( - previewX > (width - (margin)) - || - previewX < (0 + (margin)) - || - previewY > (width - (margin / 4)) - || - previewY < (0 + (margin)) - ) { - if (debug) { - console.log(`new point ${previewX},${previewY} is too close`) - } - continue - } - // if there are no previous directions to compare it with, use this one - if (previousAng == undefined) { - foundAng = true - break - } - - var isWithinDistance = checkDistance(ang, previousAng, _angleDistanceMin) - if (!isWithinDistance) { - // console.log(`not within distance(${ang} and ${previousAng} are not within ${_angleDistanceMin})`) - break - } - - foundAng = true - break + else { + x = a[0]; } - return { foundAng, ang, attempts } - } - - function getAngleDifference(ang1, ang2) { - var distance = Math.abs(modulo(ang1, 360) - modulo(ang2, 360)) - distance = Math.min(distance, 360 - distance) - return distance - } - function checkDistance(ang1, ang2, _angleDistanceMin) { - var distance = getAngleDifference(ang1, ang2) - if (debug) { - console.log(`distance between ${ang1} and ${ang2} is ${distance} (min ${_angleDistanceMin})`) + if (a[1] != b[1]) { + y = a[1] + (b[1] - a[1]) * w; + } + else { + y = a[1]; } - return distance <= _angleDistanceMin - } - function modulo(x, y) { - var xPrime = x; - while (xPrime < 0) { - xPrime += y; // ASSUMES y > 0 + if (a[2] != b[2]) { + z = a[2] + (b[2] - a[2]) * w; + } + else { + z = a[2]; } - return xPrime % y; + return [x, y, z] } diff --git a/public/tail/1.png b/public/tail/1.png index 5c8be92..72d4f50 100644 Binary files a/public/tail/1.png and b/public/tail/1.png differ diff --git a/public/tail/10.png b/public/tail/10.png new file mode 100644 index 0000000..41618ad Binary files /dev/null and b/public/tail/10.png differ diff --git a/public/tail/11.png b/public/tail/11.png new file mode 100644 index 0000000..6a397c7 Binary files /dev/null and b/public/tail/11.png differ diff --git a/public/tail/12.png b/public/tail/12.png new file mode 100644 index 0000000..7b28632 Binary files /dev/null and b/public/tail/12.png differ diff --git a/public/tail/13.png b/public/tail/13.png new file mode 100644 index 0000000..f94a001 Binary files /dev/null and b/public/tail/13.png differ diff --git a/public/tail/14.png b/public/tail/14.png new file mode 100644 index 0000000..6335a5c Binary files /dev/null and b/public/tail/14.png differ diff --git a/public/tail/15.png b/public/tail/15.png new file mode 100644 index 0000000..47064f7 Binary files /dev/null and b/public/tail/15.png differ diff --git a/public/tail/16.png b/public/tail/16.png new file mode 100644 index 0000000..2f21977 Binary files /dev/null and b/public/tail/16.png differ diff --git a/public/tail/2.png b/public/tail/2.png index f6c6466..0e16ea2 100644 Binary files a/public/tail/2.png and b/public/tail/2.png differ diff --git a/public/tail/3.png b/public/tail/3.png index 20d521d..5f46f2f 100644 Binary files a/public/tail/3.png and b/public/tail/3.png differ diff --git a/public/tail/4.png b/public/tail/4.png index 0ce5edf..9cc79a7 100644 Binary files a/public/tail/4.png and b/public/tail/4.png differ diff --git a/public/tail/5.png b/public/tail/5.png index 5891610..48bda63 100644 Binary files a/public/tail/5.png and b/public/tail/5.png differ diff --git a/public/tail/6.png b/public/tail/6.png index 833e7ac..b63989f 100644 Binary files a/public/tail/6.png and b/public/tail/6.png differ diff --git a/public/tail/7.png b/public/tail/7.png index 6867953..2508367 100644 Binary files a/public/tail/7.png and b/public/tail/7.png differ diff --git a/public/tail/8.png b/public/tail/8.png new file mode 100644 index 0000000..d65df8d Binary files /dev/null and b/public/tail/8.png differ diff --git a/public/tail/9.png b/public/tail/9.png new file mode 100644 index 0000000..21eff56 Binary files /dev/null and b/public/tail/9.png differ diff --git a/public/tail/_1.png b/public/tail/_1.png new file mode 100644 index 0000000..ddbc354 Binary files /dev/null and b/public/tail/_1.png differ