Дуги та криві Безьє
Для малювання криволінійних фігур у тега 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" />