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


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

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

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

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

2 9

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,js, вывод с использованием точек

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

Дает нам:

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

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

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 = горизонтальная линия
V = вертикальная линия
C = curveto
S = гладкая кривизна
Q = квадратичная кривая Безье
T = гладкая квадратичная кривизна Безье
А = эллиптическая Дуга
Z = closepath

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