2011-01-12 5 views
5

Скажем, у меня есть кубический путь Безье следующим образом (отформатирован для использования с функцией пути Raphael):Рисунок половина пути Безье в Рафаэль

M55 246S55 247 55 248

Просто пример. Это было взято из моего приложения рисования, где я использую курсор для рисования линии, когда пользователь удерживает кнопку мыши, вроде как карандаш или маркер. Я использую событие mousemove jquery для рисования линии между двумя точками каждый раз, когда пользователь перемещает мышь. Существует другая (контрольная точка), которая берется до того, как линия будет нарисована, чтобы можно было создать кривую Безье.

Вот мой вопрос: можно ли заставить Рафаэля нарисовать только половину заданного пути? Я знаю функцию getSubpath(), но если мое понимание кривых Безье верное, было бы довольно сложно вычислить второй аргумент. Проблема с функцией анимации заключается в том, что она создает двойные строки (то есть создает изогнутую строку, которую я хочу, и квадратную линию вокруг нее, которая не должна отображаться, возможно, потому что мышь перемещается быстрее, чем анимация может обрабатывать).

Конечно, если мой подход сам по себе является некорректным (или моим пониманием возможных решений), я бы хотел его услышать. Любая помощь будет оценена по достоинству.

+0

Что вы подразумеваете под «половиной»? Какую половину вы хотите нарисовать? – Gabe

+0

Я бы хотел нарисовать первую половину (от начала движения мыши до середины кривой Безье). Обоснованием этого является устранение краев, которые неизменно появляются, если вы просто рисуете линии от одной позиции курсора к следующему. – Fibericon

ответ

3

Это немного грязный, но, возможно, это будет ответить на него:

line[line.length] = paper.path(drawPath); //drawPath being the fill line length 

//get a subpath, being half the length of your bezier curve 
subPath = line[line.length - 1].getSubpath(0, line[line.length - 1].getTotalLength()/2); 

//remove the full-length bezier curve 
line[line.length - 1].remove(); 

//Draw your new line 
line[line.length - 1] = paper.path(subpath); 

Честно говоря, это это очень неэффективно. Но я не могу придумать, как лучше это сделать. Вы не можете просто захватить касательную и разделить на половину, так как кривая Безье будет длиннее длины касательной линии (как ворона). Это означает, что вы должны обработать линию через рафей, а затем получить субпат длиной в половину длины.

+0

Вот и все! Это действительно медленнее, но я ничего не могу сделать по этому поводу. – Fibericon

+1

Правильным решением было бы пересчитать уравнение для кубической кривой безье как функцию от t' = 2t: http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Cubic_B.C3.A9zier_curves – fuzzyTew

+0

Это действительно правда. Не могли бы вы сказать, где и как это сделать в Рафиле. – Beaker

1

Средняя точка может быть рассчитана, не зная о какой-либо функциональности в Рафаэле, которая вырезает безье пополам для вас.

От взглядов этих команд, это стандарт SVG разметки (см SVG спецификации, чтобы лучше понять его: http://www.w3.org/TR/SVG/paths.html#PathDataCubicBezierCommands)

M => MoveTo абсолютное положение 55,24 S => Гладкая кривая абсолюту 55,247 55,248

Плавная кривая может быть переписана как стандартная CurveTo или C, если вы хотите, S - это только сокращенная версия, а curveto/C вы можете легко вычислить центральную точку.

+0

Я тестировал это, но использование CurveTo, похоже, ухудшает проблему двойной линии, которую я испытываю. – Fibericon

+0

У вас есть скриншот двойной линии, которую вы получаете? –

-1

Разделение кривой Безье пополам - это лишь немного математики, ничего сложного. Вам может помочь path extensions for raphaël, и довольно просто добавить туда метод для разделения.

Часть «только часть математики» может, например, использовать De Castelau's algorithm для разделения кривой в любой заданной точке.

+1

«Разделение кривой Безье пополам - это просто математика, ничего сложного». Я думаю, что его вопрос вращается вокруг этого, и ничто слишком тяжело не отвечает на него. Возможно, вы могли бы быть более конкретными? – Beaker