I want the edges of the voronoi to end at the edge of the circle, so the circle to contain the voronoi: export default function App() {
  const [points, setPoints] = useState([]);
  const [polygons, setPolygons] = useState([]);
  const [iterations, setIterations] = useState(0);
  const [isRunning, setIsRunning] = useState(false); // To control automatic optimization
  const [maxIterations, setMaxIterations] = useState(30);

  // Generate random points initially (for rooms)
  useEffect(() => {
    const initialPoints = Array.from({ length: 5 }, () => [Math.random() * 500, Math.random() * 500]);
    setPoints(initialPoints);
  }, []);

  // Generate Voronoi polygons
  useEffect(() => {
    if (points.length > 0) {
      const delaunay = Delaunay.from(points);
      const voronoi = delaunay.voronoi([0, 0, 500, 500]); // extent: SVG size
      const voronoiPolygons = Array.from(voronoi.cellPolygons());
      const filteredPolygons = voronoiPolygons.map((polygon) => {
        return polygon.map(([x, y]) => {
          const angle = Math.atan2(y - 250, x - 250);
          const distance = Math.sqrt((x - 250) ** 2 + (y - 250) ** 2);
          if (distance > 200) {
            return [250 + 200 * Math.cos(angle), 250 + 200 * Math.sin(angle)];
          }
          return [x, y];
        });
      });
      setPolygons(filteredPolygons);
    }
  }, [points]);

  // Add a new point (representing a room) based on correct SVG click coordinates
  const handleAddPoint = (e) => {
    const svg = e.target.closest("svg");
    const svgRect = svg.getBoundingClientRect(); // Get bounding box of SVG

    // Calculate relative mouse position inside the SVG
    const newX = e.clientX - svgRect.left;
    const newY = e.clientY - svgRect.top;

    const newPoint = [newX, newY];
    setPoints([...points, newPoint]);
  };

  // Calculate the centroid of a polygon (Voronoi cell)
  const calculateCentroid = (polygon) => {
    const [centroidX, centroidY] = polygon
      .reduce((acc, [x, y]) => [acc[0] + x, acc[1] + y], [0, 0])
      .map((val) => val / polygon.length);
    return [centroidX, centroidY];
  };

  // Optimize the points using Lloyd's relaxation (moving points to centroids)
  const optimizeLayout = () => {
    setPoints((prevPoints) =>
      prevPoints.map((point, i) => {
        if (polygons[i] && polygons[i].length > 0) {
          const centroid = calculateCentroid(polygons[i]);
          return [(point[0] + centroid[0]) / 2, (point[1] + centroid[1]) / 2];
        }
        return point;
      })
    );
    setIterations((prev) => prev + 1);
  };

  // Automatic optimization effect
  useEffect(() => {
    if (isRunning && iterations < maxIterations) {
      const intervalId = setInterval(() => {
        optimizeLayout();
      }, 50);
      return () => clearInterval(intervalId);
    }
    setIsRunning(false);
  }, [isRunning, points, iterations, maxIterations]);

  // Start the automatic optimization process
  const startAutoOptimization = () => {
    setIsRunning(true); // Trigger the automatic optimization
  };

  // Stop the automatic optimization process
  const stopAutoOptimization = () => {
    setIsRunning(false); // Stop automatic optimization
  };

  const handleMaxIterationsChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    setMaxIterations(parseInt(e.target.value));
  };

  return (
    <div>
      <svg width={500} height={500} onClick={handleAddPoint}>
        <circle cx={250} cy={250} r={200} stroke="black" fill="none" />
        {polygons && polygons.map((cell, i) => <polygon key={i} points={cell.join(" ")} stroke="black" fill="none" />)}
        {points.map(([x, y], i) => (
          <circle key={i} cx={x} cy={y} r={5} fill="red" />
        ))}
      </svg>
      <input type="number" value={maxIterations} onChange={handleMaxIterationsChange} />
      <button onClick={optimizeLayout} style={{ marginTop: "10px" }}>
        Optimize Layout (Iteration: {iterations})
      </button>
      <button onClick={startAutoOptimization} disabled={isRunning} style={{ marginLeft: "10px" }}>
        Start Auto Optimization
      </button>
      <button onClick={stopAutoOptimization} disabled={!isRunning} style={{ marginLeft: "10px" }}>
        Stop Auto Optimization
      </button>
    </div>
  );