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 @@
+<!DOCTYPE html>
+<html>
+<!-- ahhh -->
+
+<body style="margin:0;">
+  <canvas id="myCanvas" width="10" height="10"
+    style="display: block;box-sizing: border-box;">
+    Your browser does not support the HTML5 canvas tag.</canvas>
+  <script>
+    let c = document.getElementById("myCanvas");
+    let ctx = c.getContext("2d");
+    ctx.canvas.width = window.innerWidth;
+    ctx.canvas.height = window.innerHeight;
+
+    let deg_per_sec = 30;
+    let time = 120;
+    let fps = 60;
+
+    centerX = ctx.canvas.width / 2;
+    centerY = ctx.canvas.height / 2;
+
+    rotation = 0; //was = j = angle
+    currentFrame = 0; //was = i
+
+    let depth = 500 //custom to npoly twist
+    
+    function render() {
+      if (currentFrame < time / (1 / fps)) {
+        setTimeout(() => {
+          render();
+          render_clear();
+          
+          colour1 = [235, 64, 52];
+          colour2 = [0, 0, 0];
+          // colour1 = [66, 18, 15];
+
+          DrawPolyTwistColour_width(10,400,-90,rotation/20,colour1,colour2)
+          // DrawPolyTwist_width(10,400,-90,rotation/20,"red")
+          // DrawSquareTwist_angle(3,400,0,rotation,"red")
+          
+        }, 1000 / fps);
+        rotation += deg_per_sec / fps; // was = j = innerRotation, now = rotation
+        currentFrame += 1; // was = i
+      }
+    }
+
+    render();
+
+
+    function DrawSquareTwist_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))))
+
+      for (let i = 0; i < 25; 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_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 = ((-1*(i-depth))**2)/(depth**2)
+        console.log(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, 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 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);
+    }
+    
+  </script>
+</body>
+
+</html>
\ 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 @@
+<!DOCTYPE html>
+<html>
+<!-- ahhh -->
+<head>
+  <title>Document</title>
+  <link rel="stylesheet" href="./css/styles.css">
+</head>
+<body style="margin:0;">
+  <canvas id="myCanvas" width="10" height="10"
+    style="display: block;box-sizing: border-box;"></canvas>
+  <div id="toolbar">
+    <br>
+    <P>Size</P>
+    <p id="outputWidth">400</p>
+    <input type="range" min="1" max="600" value="400" class="slider" id="inputWidth">
+    <br>
+    <p># of sides</p>
+    <input type="text" id="inputSides" value="5" onchange="ChangeSides(this.value)">
+    <input type="range" min="3" max="20" value="3" class="slider" id="inputSidesSlider">
+    <br>
+    <p>Colours</p>
+    <input type="color" id="colour1" name="favcolor" value="#4287f5">
+    <input type="color" id="colour2" name="favcolor" value="#42f57b">
+    <br>
+    <p>Depth</p>
+    <input type="text" id="inputDepth" value="300" onchange="ChangeDepth(this.value)">
+    <br>
+    <p>Global Rotation</p>
+    <input type="text" id="inputSetGlobalRotation" value="0" onchange="ChangeGlobalRotation(this.value)">
+    <br>
+    <p>Object Rotation</p>
+    <input type="text" id="inputSetObjectRotation" value="-90" onchange="ChangeObjectRotation(this.value)">
+    <input type="range" min="-180" max="180" value="-90" class="slider" id="inputObjectRotationSlider" onchange="ChangeObjectRotation(this.value)">
+    <br>
+    <p>Degrees Per Second</p>
+    <input type="text" id="inputDegPerSec" value="5" onchange="ChangeDegPerSec(this.value)">
+    <br>
+    <p>Controls</p>
+    <button id="resetButton" onclick="Reset()">Reset</button>
+    <div class="controls">
+      <button onclick="BackwardFrame()"><</button>
+      <button id="pauseButton" onclick="TogglePause()">Play</button>
+      <button onclick="ForwardFrame()">></button>
+    </div>
+  </div>
+</body>
+<script src="./js/math.js" type="text/javascript"></script>
+<script src="./js/objects.js" type="text/javascript"></script>
+<script src="./js/index.js"></script>
+</html>
\ 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