求自己画的图形占图形面积的百分比

问题描述 投票:0回答:1

有简单形状(红色三角形)和复杂形状(黑色“U 形”)。 我用鼠标绘制蓝色形状并愿意找到:被绘图覆盖的图形的百分比(蓝色)。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Canvas</title>
    <style>
      canvas {
        border: 1px solid black;
      }
    </style>
  </head>
  <body>
    <canvas id="canvas" width="800" height="600"></canvas>
    <script>
      const canvas = document.getElementById("canvas");
      const ctx = canvas.getContext("2d");
      const radius = 15;

      const random_shape = [
        { x: 20, y: 20, width: 20, height: 100 },
        { x: 60, y: 20, width: 20, height: 100 },
        { x: 20, y: 120, width: 60, height: 20 },
      ];

      const triangle = [
        { x: 200, y: 400 },
        { x: 400, y: 200 },
        { x: 600, y: 400 },
      ];

      let isDrawing = false;
      let lastX = 0;
      let lastY = 0;
      let pixelsInsideFigure = 0;

      function draw_random_shape() {
        for (let i = 0; i < random_shape.length; i++) {
          ctx.fillStyle = "black";
          ctx.fillRect(
            random_shape[i].x,
            random_shape[i].y,
            random_shape[i].width,
            random_shape[i].height
          );
        }
      }

      function draw_triangle() {
        ctx.beginPath();
        ctx.moveTo(triangle[0].x, triangle[0].y);
        for (let i = 1; i < triangle.length; i++) {
          ctx.lineTo(triangle[i].x, triangle[i].y);
        }
        ctx.closePath();
        ctx.fillStyle = "red";
        ctx.fill();
      }

      function handleMouseDown(e) {
        isDrawing = true;
        [lastX, lastY] = [e.offsetX, e.offsetY];
        if (pointInShape({ x: lastX, y: lastY }, random_shape)) {
          pixelsInsideFigure++;
        }
      }

      function handleMouseMove(e) {
        if (!isDrawing) return;
        ctx.strokeStyle = "blue";
        ctx.lineJoin = "round";
        ctx.lineCap = "round";
        ctx.lineWidth = radius;
        ctx.beginPath();
        ctx.moveTo(lastX, lastY);
        ctx.lineTo(e.offsetX, e.offsetY);
        ctx.stroke();
        [lastX, lastY] = [e.offsetX, e.offsetY];
        if (pointInShape({ x: lastX, y: lastY }, random_shape)) {
          pixelsInsideFigure++;
        }
      }

      function handleMouseUp() {
        isDrawing = false;
        calculatePercentage();
        pixelsInsideFigure = 0;
      }

      function clearUserInput() {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        draw_triangle();
        draw_random_shape();
      }

      function calculatePercentage() {
        const coveredArea = calculateCoveredArea(
          { x: lastX, y: lastY },
          radius
        );
        const totalArea = Math.PI * Math.pow(radius, 2);
        const coveragePercentage = (coveredArea / totalArea) * 100;

        alert(`Area Coverage Percentage: ${coveragePercentage.toFixed(2)}%`);
        clearUserInput();
      }

      function pointInShape(point, vertices) {
        let inside = false;
        const x = point.x;
        const y = point.y;
        for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
          const xi = vertices[i].x;
          const yi = vertices[i].y;
          const xj = vertices[j].x;
          const yj = vertices[j].y;
          const intersect =
            yi > y != yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi;
          if (intersect) inside = !inside;
        }
        return inside;
      }

      function calculateCoveredArea(point, radius) {
        let coveredArea = 0;
        const centerX = point.x;
        const centerY = point.y;

        for (let x = centerX - radius; x <= centerX + radius; x++) {
          for (let y = centerY - radius; y <= centerY + radius; y++) {
            const distance = Math.sqrt(
              Math.pow(x - centerX, 2) + Math.pow(y - centerY, 2)
            );
            if (distance <= radius) {
              if (pointInShape({ x: x, y: y }, random_shape)) {
                console.log("INSIDE RANDOM SHAPE");
                coveredArea++;
              }
              if (pointInShape({ x: x, y: y }, triangle)) {
                console.log("INSIDE Triangle");
                coveredArea++;
              }
            }
          }
        }

        return coveredArea;
      }

      function calculateArea(vertices) {
        let area = 0;
        for (let i = 0, j = vertices.length - 1; i < vertices.length; j = i++) {
          area +=
            (vertices[j].x + vertices[i].x) * (vertices[j].y - vertices[i].y);
        }
        return Math.abs(area / 2);
      }

      function init() {
        draw_triangle();
        draw_random_shape();

        canvas.addEventListener("mousedown", handleMouseDown);
        canvas.addEventListener("mousemove", handleMouseMove);
        canvas.addEventListener("mouseup", handleMouseUp);
      }

      init();
    </script>
  </body>
</html>

附注作为《哈利·波特 1》中的参考,我必须引导一根魔杖来适应形状。要通过技能,您必须正确覆盖该区域。

在提供的情况下,我预计能达到 60-70% 左右(左上角)。

在互联网上搜索,询问“机器人”,进行数学调整 - 没有帮助。 期望:计算和查找面积百分比的正确方法。

javascript typescript math canvas
1个回答
0
投票

我首先想到的是,您可以计算用户绘制后显示的总像素,然后您可以与目标形状像素数进行比较。只是一个想法

© www.soinside.com 2019 - 2024. All rights reserved.