Дуги та криві Безьє

Для малювання криволінійних фігур у тега path є спеціальні команди.

Дуга еліпса - A, a

Дуга малюється починаючи з останньої точки попереднього відрізка і має багато аргументів:

<path d="... A rx,ry x-axis-rotation large-arc-flag sweep-flag x,y" />

<path d="M 50,50 A 75,50 45 0 1 160,140" />
<path d="M 50,50 a 75,50 45 0 1 160,140" />

rx,ry - радіуси еліпса, частиною якого буде дуга.

x-axis-rotation - поворот осі X еліпса за годинниковою стрілкою.

large-arc-flag - прапорець, приймає значення 0 або 1; 0 - дуга меншого розміру, 1 - дуга більшого розміру.

sweep-flag - прапорець, приймає значення 0 або 1; 0 - дуга малюватиметься проти годинникової стрілки, 1 - за годинниковою стрілкою.

x,y - кінцева точка дуги.

Криві Безьє

Ці криві тісно пов'язані з моделями руху, тому у їх розрахунку принято використовувати параметр t - час.

Нехай є дві точки A та B і деяка крива, що їх з'єднує. З точки А в точку B виїзджає автомобіль, в цей момент t = 0. Коли автомобіль досягає точки B - t = 1. Таким чином, цей параметр може приймати значення від 0 до 1 (проте, від'ємні значення та значення більше одиниці також можна використовувати в розрахунках).

Існує лінійна, квадратична і кубічна функції Безьє (лінії нульового і більше третього порядку розглядати не будемо). Лінійна функція - це просто лінія, нічого цікавого. В формулі квадратичної функції використовується квадрат параметра t, а у кубічній - відповідно, куб.

Перегляньте формули на Вікіпедії.

Функція розрахунку координат конкретної точки на лінії Безьє мовою JS:

/* t -> [0..1] */
/* if 2 points: start, end */
/* if 3 points: start, middle, end */
/* if 4 points: start, start1, end1, end */


function bezierPoint(t, x1, y1, x2, y2, x3, y3, x4, y4) {
  let x, y, T = 1 - t;
  if (arguments.length > 8) {
    x = T ** 3 * x1 + 3 * T * T * t * x2 + 3 * T * t * t * x3 + t ** 3 * x4;
    y = T ** 3 * y1 + 3 * T * T * t * y2 + 3 * T * t * t * y3 + t ** 3 * y4;
  } else if (arguments.length > 6) {
    x = T * T * x1 + 2 * T * t * x2 + t * t * x3;
    y = T * T * y1 + 2 * T * t * y2 + t * t * y3;
  } else if (arguments.length > 4) {
    x = T * x1 + t * x2;
    y = T * y1 + t * y2;
  }
  return { x, y };
}

Квадратична крива Безьє - Q, q

Квадратичні криві формуються по двох кінцевих та одній контрольній точках. Перша точка береться з попередньої команди; точка {x,y} - остання; точка {x1,y1} - опорна.

Координати точок можуть лежати за межами видимої області SVG, можуть приймати від'ємні значення.

d="... Q x1,y1 x,y ...

<path d="M 50,50 Q 100,50 100,100" />
Квадратична крива Безьє

Кубічна крива Безьє - C, c

Кубічні криві формуються по двох кінцевих та двох опорних точках.

d="... C x1,y1 x2,y2 x,y ...

<path d="M 50,50 C 100,50 50,100 100,100" />
Кубічна крива Безьє

З кубічних кривих можна побудувати полікриву, продовжуючи прописувати пари контрольних точок і кінцеву точку кожної кривої:

<path d="M 50,50 C 100,50 50,100 100,100  150,100 100,150 150,150" />