2016-06-03 7 views
10

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

enter image description here

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

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

+0

Мне это нравится! Какую часть вы пытаетесь нарисовать? Вы хотите анимировать удар? –

+0

@ChrisW. нет нет нет, изображение это просто для ясности. Мне нужно нарисовать статическую кривую с помощью контрольных точек. – Legotin

+0

Хорошо, насколько вы знакомы с данными о пути? Вы определяете свою начальную точку с помощью атрибута 'M', а' C' определяет вашу начальную кривую с вашими точками, следующими за первой дугой, и 'Z' заканчивает все это. Вы можете сыграть с чем-то вроде [this] (http://blogs.sitepointstatic.com/examples/tech/svg-curves/cubic-curve.html), чтобы немного поучиться. Или, если это статично, я просто просто создаю эти объекты в Adobe Illustrator и экспортирую в SVG. Однако, не видя, что вы пробовали, или зная очки и т. Д., Этот вопрос действительно довольно широк. –

ответ

9

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

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

Некоторые опции:

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

Итог: если вам нужно, чтобы показать более высокого порядка кривых Безье, 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} 
]; 

дает нам:

enter image description here

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

+0

Спасибо, ваше решение умное, но я получил еще один интересный ответ на форуме GreenSock: http://greensock.com/forums/topic/14500-draw-bezier-curve-path-with-svg/ – Legotin

+0

уверен, и это будет нарисуйте приближение кривой, которое я объяснил как вариант №1. Он * не * рисует фактическую кривую. Если это достаточно для вас, тогда бросьте это. Тем не менее, получение «правильного» ответа на другом форуме означает, что вы либо принимаете самое лучшее, что вы получили здесь, потому что это другой форум, или вы теперь публикуете свой собственный ответ, основываясь на том, что вам дали где-то в другом месте, а затем через 24 часа примите это как правильный ответ. Вы не задаете вопросы о ТО только для себя, другие люди тоже будут иметь эту проблему, и захотят узнать, что ответ тоже =) –

+0

также, глядя на tweenmax, который не решает вашу проблему : он буквально рисует кривую * через * точки корпуса, так что теперь вам все равно нужно генерировать правильные точки на кривой с помощью функции в моем столбце, так что кривизна «сквозной» кривой выровняется с реальной кривой. И это * далеко * от быстрого и легкого. –

1

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

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

Каждая команда в list:

М = ​​MoveTo
L = LineTo
H = горизонтальный LineTo
V = вертикальная LineTo
С = curveto
S = гладкая curveto
Q = квадратичная Кривая Безье
T = гладкая квадратичная Безье curveto
A = эллиптическая дуга
Z = closepath

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