diff --git a/Catalogue/npoly twist - accident.html b/Catalogue/npoly twist - accident 1.html similarity index 100% rename from Catalogue/npoly twist - accident.html rename to Catalogue/npoly twist - accident 1.html diff --git a/Catalogue/npoly twist - accident 2.html b/Catalogue/npoly twist - accident 2.html new file mode 100644 index 0000000..2f571fe --- /dev/null +++ b/Catalogue/npoly twist - accident 2.html @@ -0,0 +1,159 @@ + + + + + + + Your browser does not support the HTML5 canvas tag. + + + + \ No newline at end of file diff --git a/Catalogue/npoly twist.html b/Catalogue/npoly twist.html index a7773c3..bde6e3a 100644 --- a/Catalogue/npoly twist.html +++ b/Catalogue/npoly twist.html @@ -22,15 +22,21 @@ rotation = 0; //was = j = angle currentFrame = 0; //was = i + let depth = 300 //custom to npoly twist function render() { if (currentFrame < time / (1 / fps)) { setTimeout(() => { render(); render_clear(); + + colour1 = [255, 0, 0]; + colour2 = [0, 0, 0]; - DrawPolyTwist_width(3,400,-90,rotation,"red") - // DrawSquareTwist_angle(3,400,0,rotation,"red") + DrawPolyTwistColour_angle(15,400,-90,rotation/20,colour1, colour2) + // DrawPolyTwist_angle(15,400,-90,rotation/20,"red") + // DrawPolyTwistColour_width(4,400,-45,rotation/4,colour1,colour2) + // DrawPolyTwist_width(10,400,-90,rotation/20,"red") }, 1000 / fps); rotation += deg_per_sec / fps; // was = j = innerRotation, now = rotation @@ -41,15 +47,17 @@ render(); - function DrawSquareTwist_angle(sides,width, rotation,innerRotation, colour){ + function DrawPolyTwist_angle(sides,width, rotation,innerRotation, colour){ let out_angle = innerRotation; - // let widthMultiplier = 169 / (239 * Math.sin(Math.PI / 180 * (135 - out_angle + 90 * Math.floor(out_angle / 90)))) - // let widthMultiplier = Math.sqrt(0.5) * 1/ (Math.sin(Math.PI / 180 * (135 - out_angle + 90 * Math.floor(out_angle / 90)))) - let widthMultiplier = Math.sqrt(0.5) * 1/ (Math.sin(Math.PI / 180 * (135 - out_angle + 90 * Math.floor(out_angle / 90)))) + let innerAngle = 180 - ((sides-2) *180/sides); + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) - for (let i = 0; i < 25; i++) { + for (let i = 0; i < depth; i++) { DrawPolygon(sides,width*widthMultiplier**i,innerRotation*i, colour) - } + } + } function DrawPolyTwist_width(sides,width, rotation,innerRotation, colour){ @@ -67,11 +75,57 @@ let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) - for (let i = 0; i < 25; i++) { + for (let i = 0; i < depth; i++) { DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colour) } } + + function DrawPolyTwistColour_angle(sides,width, rotation,innerRotation,colour1,colour2){ + let out_angle = innerRotation; + let innerAngle = 180 - ((sides-2) *180/sides); + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + let fraction = i/depth; + // let fraction = Math.cos(rad(i / 2)); + // let fraction = (-1*(i-depth)**2)/depth**2+1 + let ncolour = LerpRGB(colour1,colour2,fraction); + // let ncolour = LerpRGB(colour1,colour2,((i-depth)**2)/depth**2); + + DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colourToText(ncolour)) + } + } + + function DrawPolyTwistColour_width(sides,width, rotation,innerRotation, colour1,colour2){ + let out_angle = 0 + let innerAngle = 180 - ((sides-2) *180/sides); + let scopeAngle = innerRotation - (innerAngle*Math.floor(innerRotation/innerAngle)); + + if (scopeAngle < innerAngle/2) { + out_angle = innerAngle / (2 * Math.cos((2*Math.PI*scopeAngle)/(3*innerAngle))) - innerAngle/2 + } + else { + out_angle = -innerAngle / (2 * Math.cos( ((2*Math.PI)/3) - ((2*Math.PI*scopeAngle)/(3*innerAngle))) ) + (innerAngle*3)/2 + } + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + // let ncolour = LerpRGB(colour1,colour2,i/depth); + let fraction = i/depth; + // let fraction = Math.cos(rad(i / 2)); + // let fraction = (-1*(i-depth)**2)/depth**2+1 + let ncolour = LerpRGB(colour1,colour2,fraction); + // let ncolour = LerpRGB(colour1,colour2,((i-depth)**2)/depth**2); + + DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colourToText(ncolour)) + } + } + function DrawPolygon(sides, width, rotation, colour) { ctx.beginPath(); ctx.moveTo (centerX + width * Math.cos(rotation*Math.PI/180), centerY + width * Math.sin(rotation*Math.PI/180)); @@ -95,6 +149,22 @@ return degrees * (pi / 180); } + function colourToText(colour) { + return "rgb(" + colour[0] + "," + colour[1] + "," + colour[2] + ")" + } + + function LerpRGB(a, b, t) { + if (t < 0) { + t *= -1; + } + var newColor = [0, 0, 0]; + newColor[0] = a[0] + (b[0] - a[0]) * t; + newColor[1] = a[1] + (b[1] - a[1]) * t; + newColor[2] = a[2] + (b[2] - a[2]) * t; + return newColor; + } + + function render_clear() { diff --git a/Overlay tests/css/styles.css b/Overlay tests/css/styles.css new file mode 100644 index 0000000..f86eb85 --- /dev/null +++ b/Overlay tests/css/styles.css @@ -0,0 +1,29 @@ +body { + -webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */ + -moz-box-sizing: border-box; /* Firefox, other Gecko */ + box-sizing: border-box; /* Opera/IE 8+ */ + height:100% +} +p{ + margin: 0px; +} + +canvas { + position: absolute; +} +#toolbar { + display: flex; + flex-flow: column; + height: 100%; + + position: absolute; + padding: 0px 20px 0px 20px; + width: 500px; + height: 100vh; + background-color: rgb(189, 189, 189); +} + + +.controls{ + display: block; +} \ No newline at end of file diff --git a/Overlay tests/index.html b/Overlay tests/index.html new file mode 100644 index 0000000..87ddd3a --- /dev/null +++ b/Overlay tests/index.html @@ -0,0 +1,50 @@ + + + + + Document + + + + +
+
+

Size

+

400

+ +
+

# of sides

+ + +
+

Colours

+ + +
+

Depth

+ +
+

Global Rotation

+ +
+

Object Rotation

+ + +
+

Degrees Per Second

+ +
+

Controls

+ +
+ + + +
+
+ + + + + \ No newline at end of file diff --git a/Overlay tests/js/index.js b/Overlay tests/js/index.js new file mode 100644 index 0000000..589448a --- /dev/null +++ b/Overlay tests/js/index.js @@ -0,0 +1,143 @@ +//jshint esversion:8 +let c = document.getElementById("myCanvas"); +let ctx = c.getContext("2d"); +ctx.canvas.width = window.innerWidth; +ctx.canvas.height = window.innerHeight; +centerX = ctx.canvas.width / 2; +centerY = ctx.canvas.height / 2; + +let deg_per_sec = 5; +let time = 120; +let fps = 60; + +rotation = 0; //was = j = angle +currentFrame = 0; //was = i + +let depth = 300; //custom to npoly twist + +let paused = true; +render_clear(); + +colour1 = "#4287f5"; +colour2 = "#42f57b"; + +let width = 400 +let sides = 3 +let objectRotation = -90; + +function render() { + + if (currentFrame < time / (1 / fps)) { + setTimeout(() => { + render(); + + render_clear(); + + + // DrawPolyTwistColour_angle(sides, width, -90, rotation, colour1, colour2); + // DrawPolyTwist_angle(15,400,-90,rotation/20,"red") + DrawPolyTwistColour_width(sides,width,objectRotation,rotation,colour1,colour2) + // DrawPolyTwist_width(10,400,-90,rotation/20,"red") + + if (!paused) { + rotation += deg_per_sec / fps; // was = j = innerRotation, now = rotation + currentFrame += 1; // was = i + } + + }, 1000 / fps); + + } +} + +let toolbarShowing = true; +document.addEventListener('keydown', toggle); + +function toggle(e){ + if (e.key == "p") { + toolbarShowing = !toolbarShowing; + } + if (e.code === 'Space') { + paused = !paused; + } + + let tb = document.getElementById("toolbar"); + if (toolbarShowing) { + tb.style.display = "flex" + } + else{ + tb.style.display = "none"; + } +} + +function TogglePause(){ + let pb = document.getElementById("pauseButton"); + paused = !paused + + if (paused) { + pb.textContent = "Play" + } + else{ + pb.textContent = "Pause" + } +} +function Reset(){ + rotation = 0; //was = j = angle + currentFrame = 0; +} + +function ForwardFrame(){ + rotation += deg_per_sec / fps; // was = j = innerRotation, now = rotation + currentFrame += 1; // was = i +} +function BackwardFrame(){ + rotation -= deg_per_sec / fps; // was = j = innerRotation, now = rotation + currentFrame -= 1; // was = i +} + +const inputColour1 = document.getElementById('colour1'); +inputColour1.addEventListener('input', ChangeColour); +const inputColour2 = document.getElementById('colour2'); +inputColour2.addEventListener('input', ChangeColour); + +function ChangeColour(e) { + if (e.target.id == "colour1") { + colour1 = e.target.value; + } + else{ + colour2 = e.target.value; + } +} + +const inputWidth = document.getElementById('inputWidth'); +const outputWidth = document.getElementById('outputWidth'); +inputWidth.addEventListener('input', ChangeWidth); +function ChangeWidth(e) { + width = e.target.value; + outputWidth.textContent = e.target.value; + +} + +function ChangeDepth(dep) { + depth = dep; +} +function ChangeDegPerSec(newValue){ + deg_per_sec = newValue; +} +const inputSides = document.getElementById('inputSidesSlider'); +inputSides.addEventListener('input', ChangeSidesSlider); +function ChangeSidesSlider(e) { + sides = e.target.value; +} + +function ChangeSides(newValue){ + sides = newValue; +} + +function ChangeGlobalRotation(newValue){ + rotation = parseInt(newValue); +} +function ChangeObjectRotation(newValue){ + objectRotation = parseInt(newValue); +} + +window.onload = render; diff --git a/Overlay tests/js/math.js b/Overlay tests/js/math.js new file mode 100644 index 0000000..ae58d4e --- /dev/null +++ b/Overlay tests/js/math.js @@ -0,0 +1,81 @@ +function degToRad(deg) { + return (deg * Math.PI) / 180; +} + +function rotateMatrix2d(p, angle) { + // cos0 sin0 + // -sin0 cos0 + const angleD = degToRad(angle); + const r = [ + [Math.cos(angleD), Math.sin(angleD)], + [-Math.sin(angleD), Math.cos(angleD)], + ]; + const newPoint = [ + p[0] * r[0][0] + p[1] * r[0][1], + p[0] * r[1][0] + p[1] * r[1][1], + ]; + return newPoint; +} + +function rotateMatrix3dX(p, angle) { + // cos0 sin0 + // -sin0 cos0 + const angleD = degToRad(angle); + const r = [ + [1, 0, 0], + [0, Math.cos(angleD), -Math.sin(angleD)], + [0, Math.sin(angleD), Math.cos(angleD)], + ]; + const newPoint = [ + p[0] * r[0][0] + p[1] * r[0][1] + p[2] * r[0][2], + p[0] * r[1][0] + p[1] * r[1][1] + p[2] * r[1][2], + p[0] * r[2][0] + p[1] * r[2][1] + p[2] * r[2][2], + ]; + return newPoint; +} + +function rotateMatrix3dY(p, angle) { + // cos0 sin0 + // -sin0 cos0 + const angleD = degToRad(angle); + const r = [ + [Math.cos(angleD), 0, Math.sin(angleD)], + [0, 1, 0], + [-Math.sin(angleD), 0, Math.cos(angleD)], + ]; + const newPoint = [ + p[0] * r[0][0] + p[1] * r[0][1] + p[2] * r[0][2], + p[0] * r[1][0] + p[1] * r[1][1] + p[2] * r[1][2], + p[0] * r[2][0] + p[1] * r[2][1] + p[2] * r[2][2], + ]; + return newPoint; +} +function rotateMatrix3dZ(p, angle) { + // cos0 sin0 + // -sin0 cos0 + const angleD = degToRad(angle); + const r = [ + [Math.cos(angleD), -Math.sin(angleD), 0], + [Math.sin(angleD), Math.cos(angleD), 0], + [0, 0, 1], + ]; + const newPoint = [ + p[0] * r[0][0] + p[1] * r[0][1] + p[2] * r[0][2], + p[0] * r[1][0] + p[1] * r[1][1] + p[2] * r[1][2], + p[0] * r[2][0] + p[1] * r[2][1] + p[2] * r[2][2], + ]; + return newPoint; +} + +function projectionOrth(v) { + const p = [ + [1, 0, 0], + [0, 1, 0], + ]; + + const nPoint = [ + p[0][0] * v[0] + p[0][1] * v[1] + p[0][2] * v[2], + p[1][0] * v[0] + p[1][1] * v[1] + p[1][2] * v[2], + ]; + return nPoint; +} diff --git a/Overlay tests/js/objects.js b/Overlay tests/js/objects.js new file mode 100644 index 0000000..64b6703 --- /dev/null +++ b/Overlay tests/js/objects.js @@ -0,0 +1,140 @@ +// import math from "math.js"; +function DrawPolyTwist_angle(sides,width, rotation,innerRotation, colour){ + let out_angle = innerRotation; + let innerAngle = 180 - ((sides-2) *180/sides); + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + DrawPolygon(sides,width*widthMultiplier**i,innerRotation*i, colour) + } +} + + +function DrawPolyTwist_width(sides,width, rotation,innerRotation, colour){ + let out_angle = 0 + let innerAngle = 180 - ((sides-2) *180/sides); + let scopeAngle = innerRotation - (innerAngle*Math.floor(innerRotation/innerAngle)); + + if (scopeAngle < innerAngle/2) { + out_angle = innerAngle / (2 * Math.cos((2*Math.PI*scopeAngle)/(3*innerAngle))) - innerAngle/2 + } + else { + out_angle = -innerAngle / (2 * Math.cos( ((2*Math.PI)/3) - ((2*Math.PI*scopeAngle)/(3*innerAngle))) ) + (innerAngle*3)/2 + } + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colour) + } + +} + +function DrawPolyTwistColour_angle(sides,width, rotation,innerRotation,colour1,colour2){ + let out_angle = innerRotation; + let innerAngle = 180 - ((sides-2) *180/sides); + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + let fraction = i/depth; + // let fraction = Math.cos(rad(i / 2)); + // let fraction = (-1*(i-depth)**2)/depth**2+1 + // let ncolour = LerpRGB(colour1,colour2,fraction); + let ncolour = LerpHex(colour1,colour2,fraction); + + // let ncolour = LerpRGB(colour1,colour2,((i-depth)**2)/depth**2); + // DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colourToText(ncolour)) + DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, ncolour) + } +} + +function DrawPolyTwistColour_width(sides,width, rotation,innerRotation, colour1,colour2){ + let out_angle = 0 + let innerAngle = 180 - ((sides-2) *180/sides); + let scopeAngle = innerRotation - (innerAngle*Math.floor(innerRotation/innerAngle)); + + if (scopeAngle < innerAngle/2) { + out_angle = innerAngle / (2 * Math.cos((2*Math.PI*scopeAngle)/(3*innerAngle))) - innerAngle/2 + } + else { + out_angle = -innerAngle / (2 * Math.cos( ((2*Math.PI)/3) - ((2*Math.PI*scopeAngle)/(3*innerAngle))) ) + (innerAngle*3)/2 + } + let minWidth = Math.sin(rad(innerAngle/2))*(0.5/Math.tan(rad(innerAngle/2)))*2; + + let widthMultiplier = minWidth / Math.sin(Math.PI / 180 * (90+innerAngle/2 - out_angle + innerAngle * Math.floor(out_angle / innerAngle))) + + for (let i = 0; i < depth; i++) { + // let ncolour = LerpRGB(colour1,colour2,i/depth); + let fraction = i/depth; + // let fraction = Math.cos(rad(i / 2)); + // let fraction = (-1*(i-depth)**2)/depth**2+1 + + let ncolour = LerpHex(colour1,colour2,fraction); + // let ncolour = LerpRGB(colour1,colour2,fraction); + // let ncolour = LerpRGB(colour1,colour2,((i-depth)**2)/depth**2); + + DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, ncolour) + // DrawPolygon(sides,width*widthMultiplier**i,out_angle*i+rotation, colourToText(ncolour)) + } +} + +function DrawPolygon(sides, width, rotation, colour) { + ctx.beginPath(); + ctx.moveTo (centerX + width * Math.cos(rotation*Math.PI/180), centerY + width * Math.sin(rotation*Math.PI/180)); + + for (var i = 1; i <= sides; i += 1) { + ctx.lineTo( + centerX + width * Math.cos(i * 2 * Math.PI / sides + (rotation*Math.PI/180)), + centerY + width * Math.sin(i * 2 * Math.PI / sides + (rotation*Math.PI/180)) + ); + } + ctx.strokeStyle = colour; + ctx.lineWidth = 1; + ctx.stroke(); +} + + + +function rad(degrees) { + var pi = Math.PI; + return degrees * (pi / 180); +} + +function colourToText(colour) { + return "rgb(" + colour[0] + "," + colour[1] + "," + colour[2] + ")" +} + +function LerpHex(a, b, amount) { + + var ah = parseInt(a.replace(/#/g, ''), 16), + ar = ah >> 16, ag = ah >> 8 & 0xff, ab = ah & 0xff, + bh = parseInt(b.replace(/#/g, ''), 16), + br = bh >> 16, bg = bh >> 8 & 0xff, bb = bh & 0xff, + rr = ar + amount * (br - ar), + rg = ag + amount * (bg - ag), + rb = ab + amount * (bb - ab); + + return '#' + ((1 << 24) + (rr << 16) + (rg << 8) + rb | 0).toString(16).slice(1); +} + +function LerpRGB(a, b, t) { + if (t < 0) { + t *= -1; + } + var newColor = [0, 0, 0]; + newColor[0] = a[0] + (b[0] - a[0]) * t; + newColor[1] = a[1] + (b[1] - a[1]) * t; + newColor[2] = a[2] + (b[2] - a[2]) * t; + return newColor; +} + +function render_clear() { + ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); + ctx.fillStyle = "black"; + ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); +} \ No newline at end of file