Подтвердить что ты не робот

Нарисуйте кривую SVG Безье

У меня есть массив контрольных точек, которые представляют собой кривую Безье высокого порядка.
Как рисовать эту кривую с помощью одного SVG-пути?

введите описание изображения здесь

UPD:
Например, у меня есть набор точек: (x1, y1) (x2, y2) (x3, y3) (x4, y4) (x5, y5).
Как SVG-путь будет выглядеть в терминах C, S, Q или T?

UPD 2: РЕШЕНИЕ
Я задал этот вопрос, чтобы описать путь объекта, анимированный с помощью TweenMax.
Позже я получил ответ на форум GreenSock.
Здесь Пример CodePen.

4b9b3361

Ответ 1

Короткий ответ: вы не можете.

SVG только построил квадратные (2-й порядок) и кубические кривые (3-й порядок), тогда как кривая, которую вы показываете, является Quartic (4-й порядок). У SVG нет общей инструкции рисования "N term Bezier", поэтому вам придется идти на компромисс здесь.

Некоторые параметры:

  • преобразуем кривую в (кубические) кривые и сделаем их. Это довольно сложная проблема и не рекомендуется.
  • примерьте свою кривую в достаточном количестве точек, чтобы полигон через эти точки выглядел как кривая с разрешением и уровнем масштабирования, на которые люди будут смотреть. Это легко сделать, но, конечно, у вас больше нет "кривой", теперь у вас есть многоугольник.
  • как указано выше, но меньше точек, а затем вычислить последовательность кривой Катмулла-Рома, которая проходит через эти точки, затем преобразует эти кривые CR в кубический Bezier (они являются одним и тем же типом функции и могут быть преобразованы 1:1 от одного к другому). Это лучше, чем 2, потому что у вас есть кривая, но она может выглядеть не так, как оригинал. Конечно, чем больше очков вы используете, тем лучше результат.
  • используйте холст, чтобы нарисовать кривую Безье кривой Nth, постройте изображение из результата с помощью функции toDataURL, а затем загрузите это изображение в качестве изображения в SVG. Это будет отлично работать, но если вы используете созданный стиль SVG-пути, создание холста с помощью одного и того же стиля может стать проблемой.
  • этот список может занять очень много времени, поэтому отпустите здесь.

В нижней строке: если вам нужно показать кривые Безье более высокого порядка, SVG не является подходящей технологией для использования (я бы рекомендовал просто делать вашу анимацию с помощью холста, или еще лучше, что-то вроде d3.js или paper.js. Возможно, последний).

И если вы закончите свой собственный, функция выборки будет смехотворно простой. Кривые являются параметрическими, контролируются значением t, которое работает от 0 до 1 (включительно) и может быть записано как вложенная линейная интерполяция:

getCurvePoint(t, points) {
  if (points.length === 1) return points[0];
  var newpoints = [];
  for(var i=0,j=1; j<points.length; i++,j++) {
    newpoints[i] = lerp2d(t, points[i], points[j]);
  }
  return getCurvePoint(t,newpoints);
}

с функцией lerp, являющейся стандартной линейной интерполяционной функцией:

lerp(ratio, start, end) {
  return ratio*start + (1-ratio)*end;
}

lerp2d(ratio, start, end) {
  return {
    x: lerp(ratio, start.x, end.x),
    y: lerp(ratio, start.y, end.y)
  };
}

И простой пример jsbin: http://jsbin.com/pesutibefu/edit?html,js,output с использованием точек

var points = [
  {x:50, y:100},
  {x:50, y:250},
  {x:210, y:250},
  {x:250, y:50},
  {x:380, y:150}
];

дает нам:

введите описание изображения здесь

Хотя скетч Paper.js будет работать легче, если вам нужны анимированные красивые пути, с перетаскиваемыми контрольными точками и т.д.

Ответ 2

SVG не поддерживает кривые Безье, отличные от квадратичных и кубических. Таким образом, нет представления в терминах команд (C, S, Q или T).

Кривая Безье может быть определена двумя способами: с командой "C" для кубической или с командой "Q" для квадратичной. Эта команда имеет фиксированную длину параметров, которая 4 для квадратичных и 6 для кубических, поэтому пример строки SVG будет выглядеть как "Q 150, -300 300,0" , вы можете увидеть строку SVG, такую ​​как "Q 150, -300 300, 0 50,150 100,200" , но это всего лишь две квадратные кривые одна за другой, а количество параметров всегда всегда будет кратно 4 для "Q" и кратно 6 для "C".

Каждая команда в списке:

M = moveto
L = lineto
H = горизонтальное lineto
V = вертикальное lineto
C = curveto
S = гладкое curveto
Q = квадратичная кривая Безье
T = гладкий квадратичный Bézier curveto
A = эллиптическая арка
Z = closepath

имеет представление в JavaScript или фактически в любом другом стандартном API (.NET Drawing, Core Graphics, Android Canvas), но во всех их нет никакого метода ни для чего, кроме Кубика или Квадрата. Также, по моему опыту, я никогда не видел приложения для рисования, которое имеет функцию рисования кривой Безье более высокого порядка. Таким образом, ваш лучший вариант - упростить кривую высокого порядка до Q или C.