can you redo grid coordinates here. for example, make the same array with vertices and edges as a grid on whole canvas, but this array of vertices and edges will be static and attached at the center of this editable cube array of vertices and edges. remove all unnecessary grid code and output full modified code.: const canvas = document.createElement('canvas');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
document.body.appendChild(canvas);

const ctx = canvas.getContext('2d');
const vmcMenu = document.getElementById('vmc-menu');

    const greenDotContainer = document.createElement('div');
    document.body.appendChild(greenDotContainer);
const vertices = [
  [0, 0, 0],
  [0, 1, 0],
  [1, 1, 0],
  [1, 0, 0],
  [0, 0, 1],
  [0, 1, 1],
  [1, 1, 1],
  [1, 0, 1],
];

const edges = [
  [0, 1],
  [1, 2],
  [2, 3],
  [3, 0],
  [0, 4],
  [1, 5],
  [2, 6],
  [3, 7],
  [4, 5],
  [5, 6],
  [6, 7],
  [7, 4],
];

const scale = 0.025;
const zoom = 1;
const offsetX = 0.5;
const offsetY = 0.5;

let angleX = 0;
let angleY = 0;
let angleZ = 0;
  let bestIndex = -1;
  let bestDistance = Infinity;
let startNewEdgeIndex = -1;
let isMouseDown = false;
let prevMousePos = null;

// Red Dot
const redDot = document.getElementById('red-dot');

// Add Edge
document.getElementById('add-edge').addEventListener('click', () => {
  if (bestIndex === -1) return;
  if (startNewEdgeIndex === -1) {
    startNewEdgeIndex = bestIndex;
  } else {
    edges.push([startNewEdgeIndex, bestIndex]);
    startNewEdgeIndex = -1;
  }
});

// Remove Edge
document.getElementById('remove-edge').addEventListener('click', () => {
  if (bestIndex === -1) return;
  edges.forEach((edge, index) => {
    if (edge.includes(bestIndex)) {
      edges.splice(index, 1);
    }
  });
});

function rotateX(angle) {
  const c = Math.cos(angle);
  const s = Math.sin(angle);
  return [
    [1, 0, 0],
    [0, c, -s],
    [0, s, c],
  ];
}

function rotateY(angle) {
  const c = Math.cos(angle);
  const s = Math.sin(angle);
  return [
    [c, 0, s],
    [0, 1, 0],
    [-s, 0, c],
  ];
}

function rotateZ(angle) {
  const c = Math.cos(angle);
  const s = Math.sin(angle);
  return [
    [c, -s, 0],
    [s, c, 0],
    [0, 0, 1],
  ];
}

function project(vertex, scale, offsetX, offsetY, zoom) {
  const [x, y, z] = vertex;
  const posX = (x - offsetX) * scale;
  const posY = (y - offsetY) * scale;
  const posZ = z * scale;

  return [
    (posX * (zoom + posZ) + canvas.width / 2),
    (posY * (zoom + posZ) + canvas.height / 2),
  ];
}

function transform(vertex, rotationMatrix) {
  const [x, y, z] = vertex;
  const [rowX, rowY, rowZ] = rotationMatrix;
  return [
    x * rowX[0] + y * rowX[1] + z * rowX[2],
    x * rowY[0] + y * rowY[1] + z * rowY[2],
    x * rowZ[0] + y * rowZ[1] + z * rowZ[2],
  ];
}

function extraterrestrialTransformation(vertex, frequency, amplitude) {
  const [x, y, z] = vertex;
  const cosX = (Math.cos(x * frequency) * amplitude);
  const cosY = (Math.cos(y * frequency) * amplitude);
  const cosZ = (Math.cos(z * frequency) * amplitude);

  return [x + cosX, y + cosY, z + cosZ];
}

function getDeviation(maxDeviation) {
const t = Date.now() / 1000;
const frequency = 100 / 50;
const amplitude = maxDeviation / 10;
const deviation = Math.sin(t * frequency) * amplitude;
return deviation.toFixed(3);
}

function render() {
  ctx.fillStyle = '#FFF';
  ctx.fillRect(0, 0, canvas.width, canvas.height);

  const rotX = rotateX(angleX);
  const rotY = rotateY(angleY);
  const rotZ = rotateZ(angleZ);

  // Extraterrestrial transformation parameters
  const frequency = 1;
  const amplitude = 0.8;

  const transformedVertices = vertices.map(vertex => {
    const extraterrestrialVertex = extraterrestrialTransformation(vertex, frequency, amplitude);
    const cx = extraterrestrialVertex[0] - offsetX;
    const cy = extraterrestrialVertex[1] - offsetY;
    const cz = extraterrestrialVertex[2] - offsetY;

    const rotated = transform(transform(transform([cx, cy, cz], rotX), rotY), rotZ);

    return [
      rotated[0] + offsetX,
      rotated[1] + offsetY,
      rotated[2] + offsetY,
    ];
  });

  const projectedVertices = transformedVertices.map(vertex => project(vertex, canvas.height * scale, offsetX, offsetY, zoom));

ctx.lineWidth = 2;
ctx.strokeStyle = 'hsla(' + (angleX + offsetX + angleY + offsetY) * 55 + ', 100%, 30%, 0.8)';
ctx.beginPath();

for (let edge of edges) {
const [a, b] = edge;
const [x1, y1] = projectedVertices[a];
const [x2, y2] = projectedVertices[b];

const dist = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2 + (y2 - x1) ** 2 + (x2 - y1));
const angle = Math.atan2(y2 - y1, x2 - x1, x2 - y1, y2 - x1);

// Calculate control point for curved edge
const cpDist = 0.005 * dist;
const cpX = (x1 + x2) / 2 + cpDist * Math.cos(angle - Math.PI / 2) * getDeviation(0.2);
const cpY = (y1 + y2) / 2 + cpDist * Math.sin(angle - Math.PI / 2) * getDeviation(0.2);

ctx.moveTo(x1, y1, x2, y2);
ctx.quadraticCurveTo(cpX, cpY, x2, y2, x1, y1);
}

ctx.stroke();

canvas.addEventListener('mousedown', (event) => {
  isMouseDown = true;
  prevMousePos = { x: event.clientX, y: event.clientY };
});

canvas.addEventListener('mouseup', () => {
  isMouseDown = false;
  prevMousePos = null;
});

canvas.addEventListener('mousemove', (event) => {
  const mousePos = {
    x: event.clientX - canvas.getBoundingClientRect().left,
    y: event.clientY - canvas.getBoundingClientRect().top
  };
  
  bestIndex = -1;
  bestDistance = Infinity;

  projectedVertices.forEach((currVertex, index) => {
    const distance = Math.hypot(
      currVertex[0] - mousePos.x,
      currVertex[1] - mousePos.y
    );
    if (distance < bestDistance) {
      bestIndex = index;
      bestDistance = distance;
    }
  });
  
  if (bestDistance < 10 && bestIndex !== -1) {
    vmcMenu.style.display = 'block';
    vmcMenu.style.left = mousePos.x + 'px';
    vmcMenu.style.top = mousePos.y + 'px';

    document.getElementById('vmc-vertex-x').value = vertices[bestIndex][0];
    document.getElementById('vmc-vertex-y').value = vertices[bestIndex][1];
    document.getElementById('vmc-vertex-z').value = vertices[bestIndex][2];

    document.getElementById('vmc-vertex-x').dataset.vertexIndex = bestIndex;
    document.getElementById('vmc-vertex-y').dataset.vertexIndex = bestIndex;
    document.getElementById('vmc-vertex-z').dataset.vertexIndex = bestIndex;

    redDot.style.display = 'block';
    redDot.style.left = projectedVertices[bestIndex][0] - 3 + 'px';
    redDot.style.top = projectedVertices[bestIndex][1] - 3 + 'px';
  } else {
    vmcMenu.style.display = 'none';
    redDot.style.display = 'none';
  }

  if (isMouseDown && prevMousePos) {
    const deltaX = event.clientX - prevMousePos.x;
    const deltaY = event.clientY - prevMousePos.y;

    angleY += deltaX * 0.01;
    angleX += deltaY * 0.01;

    prevMousePos = { x: event.clientX, y: event.clientY };
  }
});

function updateVertexValue(event, indexToUpdate) {
  const newValue = parseFloat(event.target.value);
  const vertexIndex = parseInt(event.target.dataset.vertexIndex);

  if (!isNaN(newValue) && vertexIndex >= 0) {
    vertices[vertexIndex][indexToUpdate] = newValue;
  }
}

document.getElementById('vmc-vertex-x').addEventListener('input', (event) => {
  updateVertexValue(event, 0);
});
document.getElementById('vmc-vertex-y').addEventListener('input', (event) => {
  updateVertexValue(event, 1);
});
document.getElementById('vmc-vertex-z').addEventListener('input', (event) => {
  updateVertexValue(event, 2);
});

angleX += +getDeviation(0.0005);
angleY += +getDeviation(0.0005);
angleZ += +getDeviation(0.0005);
  
  

  requestAnimationFrame(render);
  
}


// Grid related variables
    const gridSpacing = 50; // Spacing between grid lines (in px)
    const gridPoints = []; // Array to store grid points
    let displayGrid = true; // A flag to toggle grid display on and off

    for (let i = 0; i < canvas.width; i += gridSpacing) {
      for (let j = 0; j < canvas.height; j += gridSpacing) {
        gridPoints.push({ x: i, y: j });
        const dot = document.createElement('div');
        dot.className = 'green-dot';
        dot.style.left = (i - 2) + 'px';
        dot.style.top = (j - 2) + 'px';
        dot.style.display = displayGrid ? '' : 'none';
        greenDotContainer.appendChild(dot);
      }
    }

    // Renders grid lines
    function renderGrid() {
      if (!displayGrid) return;
      ctx.strokeStyle = '#0F0';
      ctx.lineWidth = 1;
      for (let i = 0; i <= canvas.width; i += gridSpacing) {
        ctx.beginPath();
        ctx.moveTo(i, 0);
        ctx.lineTo(i, canvas.height);
        ctx.stroke();
      }
      for (let i = 0; i <= canvas.height; i += gridSpacing) {
        ctx.beginPath();
        ctx.moveTo(0, i);
        ctx.lineTo(canvas.width, i);
        ctx.stroke();
      }
    }

    // Adds a button to toggle the grid display
    const gridToggleButton = document.createElement('button');
    gridToggleButton.innerText = 'Toggle Grid';
    vmcMenu.insertBefore(gridToggleButton, document.getElementById('add-edge'));

    gridToggleButton.addEventListener('click', () => {
      displayGrid = !displayGrid;
      if (displayGrid) {
        greenDotContainer.style.display = 'block';
      } else {
        greenDotContainer.style.display = 'none';
      }
    });
  
renderGrid();
requestAnimationFrame(render);

window.addEventListener("resize", () => {
  canvas.width = window.innerWidth;
  canvas.height = window.innerHeight;
});