You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JS基于Chart.js实现任意角度旋转菲涅尔椭圆异常求解

问题根源

代码存在3个核心错误,直接导致椭圆变形、锚点偏移、图形无法闭合:

  • 坐标变换逻辑错误:当前平移基准为椭圆几何中心,未按要求将旋转锚点设置为起始点;菲涅尔椭圆的两个焦点本应对应给定的起止点,现有参数变换后焦点位置完全偏移。
  • Chart.js配置错误:将x坐标作为labels传入会触发类目轴渲染逻辑,x轴不会按实际数值间距排布点位,连线自然扭曲。
  • 点集首尾未严格重合:步长累加生成点的逻辑受浮点数精度影响,最后一个点无法和起点完全对齐,会出现闭合缺口。
修复方案
  1. 调整坐标变换顺序:标准椭圆参数方程(中心在原点、长轴沿x轴)的两个焦点坐标为(-a, 0)和(a, 0),旋转对应角度后,将焦点(-a, 0)平移到起始点(x1,y1),另一个焦点会自动落在终点(x2,y2),完全符合菲涅尔区定义,同时锚点固定为起始点。
  2. 将图表类型改为scatter散点图,直接传入{x: xval, y: yval}格式的坐标数据,x/y轴均使用线性轴,保证坐标准确映射。
  3. 循环结束后手动追加起点坐标到点集末尾,强制图形闭合,可适当提高点密度让椭圆边缘更平滑。
修复后完整可运行代码
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Fresnel Zone Demo</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
    <style>
      .chart-container {
        width: 600px;
      }
    </style>
  </head>
  <body>
    <div class="chart-container">
      <canvas id="myChart"></canvas>
    </div>
    <script>
      const step = (2 * Math.PI) / 60;
      const f = 217.25;
      const x1 = 0, y1 = 130;
      const x2 = 15, y2 = 250;
      const fr = f * Math.pow(10, 6);
      const c = 2.997925 * Math.pow(10, 8);
      const lambda = c / fr;
      const points = [];
      const a = (1 / 2) * Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2));
      const r = Math.sqrt((lambda * a) / 2);
      const w = Math.atan2(y2 - y1, x2 - x1);

      for (let i = 0; i <= 2 * Math.PI; i += step) {
        const xval = a * Math.cos(i);
        const yval = r * Math.sin(i);
        const xRot = xval * Math.cos(w) - yval * Math.sin(w);
        const yRot = xval * Math.sin(w) + yval * Math.cos(w);
        const xnew = x1 + xRot + a * Math.cos(w);
        const ynew = y1 + yRot + a * Math.sin(w);
        points.push({x: xnew, y: ynew});
      }
      points.push(points[0]);

      const data = {
        datasets: [
          {
            label: '第一菲涅尔区',
            data: points,
            borderColor: "rgba(0,0,0,1)",
            borderWidth: 2,
            fill: false,
            tension: 0
          },
          {
            data: [{x:x1,y:y1}, {x:x2,y:y2}],
            pointRadius: 5,
            pointBackgroundColor: 'red',
            showLine: false
          }
        ]
      };
      const config = {
        type: "scatter",
        data: data,
        options: {
          responsive: true,
          scales: {
            x: {
              type: 'linear',
              beginAtZero: true,
              ticks: {
                maxTicksLimit: 5
              }
            },
            y: {
              beginAtZero: true,
              maxTicksLimit: 5
            }
          }
        }
      };
      const mychart = new Chart(document.getElementById("myChart"), config);
    </script>
  </body>
</html>
效果说明
  • 渲染出的椭圆为标准第一菲涅尔区,两个焦点刚好落在设定的起止点上,旋转锚点固定为起始点(x1,y1)
  • 图形完全闭合无缺口,无扭曲变形,调整step值可修改椭圆平滑度
  • 红色标记点为起止点,可直接验证位置是否符合预期

内容的提问来源于stack exchange,提问作者Priyanka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 22:48:36