首页 > 解决方案 > 椭圆弧的边界

问题描述

我需要找到 2D 变换椭圆弧的确切边界。

录入数据如下:

  1. a - 椭圆半径 x
  2. b - 椭圆半径 y
  3. transform - 0 平移的 2D 变换 (a, b, c, d, tx, ty)
  4. startAngle - 圆弧起始角度
  5. endAngle - 圆弧结束角度

我已经使用这个主题答案来找到变换椭圆的边界 https://math.stackexchange.com/questions/91132/how-to-get-the-limits-of-rotated-ellipse

它工作正常。

我现在拥有的

const rx2 = radiusX * radiusX;
const ry2 = radiusY * radiusY;

let maxX = Math.sqrt(rx2 * transform.a * transform.a + ry2 * transform.c * transform.c);
let maxY = Math.sqrt(rx2 * transform.b * transform.b + ry2 * transform.d * transform.d);
let minX = -maxX;
let minY = -maxY;

下一步是找到点 p1、p2、p3、p4(见图)然后我可以检查哪些点在 startAngle 和 endAngle 内。

所需积分

椭圆的方程为: 简单方程

变换椭圆的方程应为: 变换方程

为了找到所需的点,必须为 x 和 y 求解最后一个方程

标签: automatic-ref-countingboundsellipse

解决方案


我有这个。

所以我只需要对点(minX,minY)应用逆变换;(最大X,最小Y);(最大X,最大Y);(最大X,最小Y);然后使用简单的椭圆(上面提到过)和直线方程找到四个交点,然后将其转换为全局坐标乘以进行变换。

这是一点的代码

arcLineIntersection(lineStart, lineEnd, rx2, ry2, out) {
    const lineK = (lineEnd.y - lineStart.y) / (lineEnd.x - lineStart.x);

    if (Number.isFinite(lineK)) {
      const lineB = lineStart.y - lineK * lineStart.x;

      const a = lineK * lineK + ry2 / rx2;
      const b = 2 * lineK * lineB;

      const x = -b / (2 * a);
      const y = lineK * x + lineB;

      out.set(x, y);
    } else {
      const x = lineStart.x;
      const y = Math.sqrt(ry2 * (1 - x * x / rx2));

      out.set(x, y);
    }
  }

结果


推荐阅读