Во время разработки одного приложения я столкнулся с необходимостью рисовать эллипсы под произвольным углом в холсте с помощью JavaScript. Использовать какие-либо фреймворки в таком простом проекте мне не хотелось, поэтому я отправился на поиски мануальной статьи на эту тему.
Поиски не увенчались успехом, поэтому мне пришлось разбираться с проблемой самому, и я решил поделиться своим опытом с вами.
Формализуем задачу.
Нам нужна функция drawEllipse(координаты, размеры, вектор) , Где:
- coords — координаты центра эллипса — массив [x, y]
- размеры — длины большой и малой полуосей эллипса — массив [a, b]
- вектор — вектор [x, y] наклона эллипса
В качестве первого метода были выбраны кривые Безье.
Для построения такой кривой необходимы четыре точки: начало, конец и две контрольные точки.
Искомый эллипс будет состоять из двух таких кривых, и нетрудно догадаться, что упомянутые точки для каждой из них будут вершинами прямоугольника.
Давайте рассмотрим наш эллипс.
- У нас есть некоторый вектор
Найдем единичный вектор
Найдем единичный вектор
Для этого вспомним свойство скалярного произведения векторов обращаться в нуль, если они перпендикулярны:
Таким образом: - Найдем векторы
, точки А 1 , А 2 , Б 1 , Б 2
- Найдем векторы
, точки С 1 , С 2 , С 3 , С 4
- Напомним, что для рисования эллипса нам нужны две кривые Безье:
- 1-й имеет отправную точку B 1 , финал Б 2 , проходит через точку А 1
- 2-й имеет отправную точку B 2 , финал Б 1 , проходит через точку А 2
Недолго думая, я сначала подставил таковыми вершины прямоугольника, в который был вписан эллипс.
Это решение оказалось ошибкой, поскольку если мы посмотрим на построение кривой Безье, то обнаружим, что она не касается отрезка, соединяющего две контрольные точки.
Изобразим момент построения кривой Безье в той точке, в которой она (кривая) будет ближе всего к отрезку между контрольными точками.
В нашем случае это будет выглядеть так:
Из рисунка видно, что расстояние от этой точки (А 1 ) на отрезок между контрольными точками (C 1 , С 2 ) составит четверть расстояния между центром искомого эллипса (О) и таким же отрезком (С 1 , С 2 ), то есть: - Обозначим ОА через x. Давайте решим уравнение
Таким образом, чтобы получить эллипс с нужными параметрами, нам нужно умножить вектор
по параметру
, а затем вернитесь к расчетам, описанным в пунктах 1-4. В результате получаем наборы точек ( Б 1 , С 1 , С 2 , Б 2 И Б 2 , С 3 , С 4 , Б 1 ), чтобы построить две кривые Безье, которые вместе представляют желаемую форму.
На самом деле демо и код:
Теги: #JavaScript #canvas #ellipse #geometry #JavaScript #canvasfunction drawEllipse(ctx, coords, sizes, vector) {
-
Мой Штрих-Код. Код128
19 Oct, 24 -
Вспоминая Прошлое
19 Oct, 24