Границы эллиптической дуги - PullRequest
0 голосов
/ 04 марта 2019

Мне нужно найти точные границы преобразованной двумерной дуги эллипса.

Входные данные:

  1. a - радиус эллипса x
  2. b - радиус эллипса y
  3. transform - 2D преобразование с переводом 0 (a, b, c, d, tx, ty)
  4. startAngle - начальный угол дуги
  5. endAngle - конечный угол дуги

Я использовал ответ на эту тему, чтобы найти границы преобразованного эллипса https://math.stackexchange.com/questions/91132/how-to-get-the-limits-of-rotated-ellipse

Itработает отлично.

Что у меня сейчас есть

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

1 Ответ

0 голосов
/ 06 марта 2019

У меня есть это.

Так что все, что мне нужно, это применить инвертированное преобразование к точкам (minX, minY);(maxX, minY);(maxX, maxY);(maxX, minY);А затем используйте простой эллипс (упомянутый выше) и линейные уравнения, чтобы найти четыре точки пересечения, которые затем должны быть преобразованы в глобальные координаты, умножающиеся для преобразования.

Вот код для одной точки

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);
    }
  }

Результат

...