投针实验计算Π值的可视化

H2O-C2H5OH / 2023-07-28 / 原文

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>needleProblem</title>
</head>
<body>

  <canvas id="myCanvas"></canvas>
  <br>
  <input id="times" type="text">
  <button id="submit">提交</button>
  
  <script type="text/javascript">
  
    // 初始化
    const myCanvas = document.getElementById("myCanvas");
    myCanvas.width = 500;   // 只能在这里设置,CSS中的设置没有作用
    myCanvas.height = 500;
    const context = myCanvas.getContext("2d");
    const a = 10;
    
    let arr = [];
    // 绘制线
    for (let i = 0; i < myCanvas.height; i += a) {
      context.beginPath();
      context.moveTo(0,i);
      context.lineTo(myCanvas.width,i);
      context.closePath();
      context.stroke();
      arr.push(i);
    }
    
    // 绘制针
    const submit = document.getElementById("submit");
    submit.addEventListener("click", function() {
      const times = document.getElementById("times").value;
      const len = a / 2.0;
      let timesPoint = 0;
      for (let i = 0; i < times; i++) {
        let x1 = Math.random() * myCanvas.width;
        let y1 = Math.random() * myCanvas.height;
        let angle = Math.random() * 2 * Math.PI - Math.PI;
        let x2 = x1 + len * Math.cos(angle);
        let y2 = y1 + len * Math.sin(angle);
        context.beginPath();
        context.moveTo(x1, y1);
        context.lineTo(x2, y2);
        context.closePath();
        context.strokeStyle="red";
        context.stroke();
    
        // 检测针与线的交点
        let length = arr.length;
        for (let j = 0; j < length; j++) {
          if ((y1 - arr[j]) * (y2 - arr[j]) <= 0) {
            timesPoint++;
          }
        }
      }
      alert(times/timesPoint);
    });
  </script>
</body>
</html>