Цитата:
"Свершилось!!!!! Я бился над этим больше чем пол года. Еще сырая версия, но работает вполне корректно. Скоро приведу в порядок и... эх.... заживем!
Главное, и единственное пока, что делает Path, -- это перевод расчета позиции объекта с кривой в прямую. Т.е. рассчитываем только один параметр: позиция объекта на длине пути. Затем с помощью getPointByPosition получаем координаты x, y. Таким образом задача сводится к вычислению только одного параметра: позиция объекта на длине пути. Чудить на базе этого можно уже сколько угодно. Например и скорость задавать с помощью Path и брать, например _y в качестве скорости."
Path
getPointByPosition
x
y
_y
Конец цитаты. Исходный код:
// author: Ivan Dembicki Path = function () { this.path_points=arguments.toString(), this.path_length=0; var x_array = [], y_array = [], k = 0, i, len = arguments.length, x0 = arguments[0] || 0, y0 = arguments[1] || 0, x1, y1, x2, y2, ln, o, a1, a2, a3, a4, a, b, c, d, e, a2t, sa; var s = Math.sqrt, l = Math.log, p = Math.pow; for (i=2; i<len; i += 4) { x1=arguments[i] || 0, y1=arguments[i+1] || 0, x2=arguments[i+2] || 0, y2=arguments[i+3] || 0, ln=this["ln"+k++]=[{_y:y0, _x:x0}, {_y:y1, _x:x1}, {_y:y2, _x:x2}]; // ASSetPropFlags(this, "ln"+(k-1), 7, 1) o=ln[3]={}, a1=o.a1=x0-2*x1+x2, a2=o.a2=y0-2*y1+y2, a3=o.a3=x0-x1, a4=o.a4=y0-y1, a=o.a=4*(a1*a1+a2*a2), b=o.b=-8*(a1*a3+a2*a4), c=o.c=4*(a3*a3+a4*a4), e=o.e=Math.sqrt(c), d=s(c+b+a), sa=s(a), a2t=a*2, ln[4]=(2*sa*(d*(b+a2t)-e*b)+(b*b-4*a*c)*(l(2*e+b/sa)-l(2*d+(b+a2t)/sa)))/(8*p(a, (3/2))); this.path_length += ln[4]; x0=x2, y0=y2; } this.segments = k--; // comment it! _root.lineStyle(0, 0, 30), _root.moveTo(this.ln0[0]._x, this.ln0[0]._y), _root.curveTo(this.ln0[1]._x, this.ln0[1]._y, this.ln0[2]._x, this.ln0[2]._y), _root.curveTo(this.ln1[1]._x, this.ln1[1]._y, this.ln1[2]._x, this.ln1[2]._y); _root.curveTo(this.ln2[1]._x, this.ln2[1]._y, this.ln2[2]._x, this.ln2[2]._y); // end comment it }; tmp = Path.prototype={}; tmp.getPointByPosition = function(poz) { if (poz<0 || poz>this.path_length) { return {_x:this.ln0[0]._x, _y:this.ln0[0]._y}; } if (this.segments<1) { return false; } var i = 0, ln, len = 0, ff = 0; for (i; i<=this.segments; i++) { ln=this["ln"+i], len += ln[4]; if (len>poz) { ff = (poz-(len-ln[4]))/ln[4]; break; } } var s = Math.sqrt, l = Math.log, p = Math.pow, abs = Math.abs; var fn = function (ff) { var o = ln[3], a1 = o.a1, a2 = o.a2, a3 = o.a3, a4 = o.a4, a = o.a, b = o.b, c = o.c, e = o.e, i = 1, st = 1, f_l = ln[4], t_l = ff*f_l, max_i = 100, d, sa, a2i; while (max_i--) { d=s(c+i*(b+a*i)), sa=s(a), a2i=a*2*i, f_l=(2*sa*(d*(b+a2i)-e*b)+(b*b-4*a*c)*(l(2*e+b/sa)-l(2*d+(b+a2i)/sa)))/(8*p(a, (3/2))); if (abs(f_l-t_l)<.000001) { return i; } st /= 2, i += f_l<t_l ? st : f_l>t_l ? -st : 0; } return i; }; var f = fn(ff), p0 = ln[0], p1 = ln[1], p2 = ln[2], e = 1-f, ee = e*e, ff = f*f, b = 2*f*e; return {_x:p2._x*ff+p1._x*b+p0._x*ee, _y:p2._y*ff+p1._y*b+p0._y*ee}; }; delete tmp;
Как это использовать:
/// TEST _root.createEmptyMovieClip("mc", 0); _root.mc.lineStyle(5, 0xFF0000, 100); _root.mc.lineTo(.2, 0); _root.mc.tween_path = new Path(0, 0, 100, 0, 100, 100, 100, 200, 450, 380, 0, 300, 0, 0); _root.mc.speed = _root.mc.path_position=0; _root.mc.onEnterFrame = function() { if (this.path_position>this.tween_path.path_length) { this.path_position = 0; } this.path_position += this.speed += .01; var poz = this.tween_path.getPointByPosition(this.path_position); this._x=poz._x, this._y=poz._y; };
Скачать класс Path: http://www.sharedfonts.com/Path.as.
Поздравляю! и радуюсь. вещь очень полезная.
klasnaya vesh congratulation !
osobenno za to shto eto as1.0 a ne as2.0 kotoriy ya ne slishkom lyublyu ;)
всего-то года на два-три после моей реализации. ;) Хоть бы упомянул откуда руки растут, ведь сам же сидел на тех семинарах когда я расказывал про эту технику.
Честно говоря "навеяло" не совсем в моем стиле. К сожалению, я не помню или не совсем понимаю о каком рассказе на семинаре идет речь. Безусловно, если я присутствую на семинаре я стараюсь слушать докладчиков, особенно до того как привезут пиво :). И объем моих знаний существенно расширялся за счет семинаров. В том числе, возможно, и благодаря твоим докладам. Однако, как это ни прискорбно признать, те, кто действительно заслуживают лавров, остались за кадром. Я не математик. В этом проекте скорее выступил как организатор, которому очень нужно: я лишь замучил вопросами ребят, математиков, на форуме http://algolist.manual.ru/forum/ и затем, на готовых формулах вычисления длины сегмента безье, построил бисекцию. Всё. Еще раз спасибо за помощь участникам алголист форума. Что касается доклада... В любом случае, если я на нем присутствовал, доклад стал частью моих знаний, за которые в любом случае спасибо еще раз.
Iv, спасибо. как всегда, руль :). это очень хорошо, что есть умные мужчины с такими математическими мозгами. которые умеют много гитик ;). //offt: Рост, объявись pls в icq.
Iv, признаю твой ответ убедительным, и прошу принять мои извинения за некоторую допущеную резкость.
а алголист действительно очень, я бы даже сказал, чрезвычайно, полезный ресурс.