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

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

enter image description here

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

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

2 ответов


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

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

варианты:

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

итог: Если вам нужно показать кривые Безье более высокого порядка, SVG не является подходящей технологией для использования (я бы рекомендовал просто делать анимацию с помощью холста или, еще лучше, что-то вроде d3.js или бумаги.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 И. С.,вывод через точки

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

дает нам:

enter image description here

хотя бумагу.Яш эскиз будет проще работать, если вам нужны анимированные красивые пути,с перетаскиваемыми контрольными точками и т. д.


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
Л = строки, чтобы
Ч = горизонтальные строки, чтобы
V = вертикальный строки, чтобы
C = curveto
S = гладкая кривизна
Q = квадратичная кривая Безье
T = гладкая квадратичная кривизна Безье
Эллиптический тренажер Arc
Z = closepath

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