Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 1.0/2.0 (http://www.flasher.ru/forum/forumdisplay.php?f=93)
-   -   Веревка (http://www.flasher.ru/forum/showthread.php?t=82931)

tov_diatel 24.07.2006 15:15

Веревка
 
Народ как делать веревку понятно(у Дембицкого в уроках хорошо написано).Вопрос в следующем: как сделать веревку фиксированого размера?У него там просто не веревка скорее резинка!

F_Flash 24.07.2006 16:03

Хороший вопрос%)

размер вревки это длина кривой. Для этого нам хотябы нужно ее научиться находить.

длина кривой вычисялется по фрмуле

http://ru.wikipedia.org/wiki/%D0%94%...B2%D0%BE%D0%B9


далее смотрим по какой формуле мы строим кривую если это бикубический сплайн(кривая безье) то есть топик

http://algolist.manual.ru/forum/show...036/page//vc/1


во флеше используется для пострениея кривых

http://people.nnov.ru/fractal/Splines/Bezier.htm


вот код для флеша
Код:


// quadratic bezier functions
function B1 (t) {
        return (t*t);
}
function B2 (t) {
        return (2*t*(1-t));
}
function B3 (t) {
        return ((1-t)*(1-t));
}

// draw spline routine : called from RedrawClip
function DrawSpline () {
        count = 0;
        // change this for smooth line
        detailBias = 1/23;
        level = 1;
        do {
                x = cP1._x*B1(count)+cP2._x*B2(count)+cP3._x*B3(count);
                y = cP1._y*B1(count)+cP2._y*B2(count)+cP3._y*B3(count);
                if (level>1) {
                        attachMovie("line", "line"+level, level+10);
                        _root["line"+level]._x = x;
                        _root["line"+level]._y = y;
                        _root["line"+level]._rotation = Math.atan2(yold-y, xold-x)*180/(Math.PI);
                        _root["line"+level]._xscale = _root["line"+level]._yscale = Math.sqrt((xold-x)*(xold-x)+(yold-y)*(yold-y));
                }
                yold = y;
                xold = x;
                ++level;
                count += detailBias;
        } while (count<=1);
}

// main init : put 3 control point to stage
for (i=1; i<=3; i++) {
        attachMovie("cdot", "cP"+i, i);
        _root["cP"+i]._x = random(540);
        _root["cP"+i]._y = random(400);
}

для вычисления длины я просто прибалял расстояния от точки до сдледущей точки аппроксимации.На выходе погрешнось зависит от количесва сегментов для апроксимации.

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

tov_diatel 24.07.2006 17:21

Ну для того что бы веревка была более менее реалистична необходимо как минимум точек пять имеющих вес!что бы она реалистично прогибалась!Кста спасибо за ответ ща буду смотреть че ты мне скинул!

F_Flash 24.07.2006 17:43

будем говорить так. Веревка это кривая второго порядка

ее нужно разбить на сегменты которые строятся из 3-х точек как во флеше. или из 2-х точек + 2х точек касательных.

Так вот общая длоина будет сложена из суммы длин этих сегменов.

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

далее поведение веревки

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


В любом случае ты должна определиться что у тябы будет постоянным а что нужэно достроить до той длины что необходима.

Iv 24.07.2006 20:01

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

this.createEmptyMovieClip("line", 1);
this.line.init = function(num, len) {
        this.len = len;
        this.point = [];
        for (var i = 0; i<num; i++) {
                var t = new Object();
                t.x = 0+i*20;
                t.y = 200;
                this.point.push(t);
        }
};
this.xstep = 0;
this.drag_x = 0;
this.ystep = 0;
this.drag_y = 0;
                this.target_x = Math.random()*Stage.width;
                this.target_y = Math.random()*Stage.height;
//
this.onEnterFrame = function() {
        if (!(random(20))) {
                this.target_x = Math.random()*Stage.width;
                this.target_y = Math.random()*Stage.height;
        }
        this.xstep += (this.target_x-this.drag_x)*0.005;
        this.xstep *= .95;
        this.drag_x += this.xstep;
        this.ystep += (this.target_y-this.drag_y)*0.005;
        this.ystep *= .95;
        this.drag_y += this.ystep;
        this.line.onUpdate(this.drag_x, this.drag_y);
};
this.line.onUpdate = function(x, y) {
        this.point[0].x = x
        // || this._xmouse;
        this.point[0].y = y
        // || this._ymouse;
        this.clear();
        this.lineStyle(0, 0, 100);
        this.moveTo(this.point[0].x, this.point[0].y);
        for (var i = 1, len = this.point.length; i<len; i++) {
                //[x1,y1] и [x2,y2] - координаты предыдущей и текущей точки соответственно
                var x1 = this.point[i-1].x, y1 = this.point[i-1].y;
                var x2 = this.point[i].x, y2 = this.point[i].y;
                // xd и yd - разница расстояний между точками
                var xd = x2-x1, yd = y2-y1;
                //dist - расстояние между точками
                var dist = Math.sqrt(xd*xd+yd*yd);
                //коррекция расстояния между точками до требуемого (через подобие)
                this.point[i].x = x1+(xd*this.len)/dist;
                this.point[i].y = y1+(yd*this.len)/dist;
                this.lineTo(this.point[i].x, this.point[i].y);
        }
};
//линия с 200 точками и расстоянием 5px между ними
this.line.init(200, 3);


etc 24.07.2006 20:13

Упрощённый вариант (+гравитация и "ветер" (горизонтальная гравитация)):
Код:

this.createEmptyMovieClip("line", 1);
this.line.init = function(num, len) {
        this.len = len;
        this.point = [];
        for (var i = 0; i<num; i++) {
                var t = new Object();
                t.x = 0+i*20;
                t.y = 200;
                this.point.push(t);
        }
};
this.line.onEnterFrame = function() {
        this.gravity = 10;
        this.wind = 2;
        this.point[0].x = _root._xmouse;
        this.point[0].y = _root._ymouse;
        this.clear();
        this.lineStyle(0, 0, 100);
        this.moveTo(this.point[0].x, this.point[0].y);
        for (var i = 1, len = this.point.length; i<len; i++) {
                //[x1,y1] и [x2,y2] - координаты предыдущей и текущей точки соответственно
                var x1 = this.point[i-1].x, y1 = this.point[i-1].y;
                var x2 = this.point[i].x, y2 = this.point[i].y;
                // xd и yd - разница расстояний между точками
                var xd = x2-x1+this.wind;
                var yd = y2-y1+this.gravity;
                //dist - расстояние между точками
                var dist = Math.sqrt(xd*xd+yd*yd);
                //коррекция расстояния между точками до требуемого (через подобие)
                this.point[i].x = x1+(xd*this.len)/dist;
                this.point[i].y = y1+(yd*this.len)/dist;
                this.lineTo(this.point[i].x, this.point[i].y);
        }
};
//линия с 200 точками и расстоянием 5px между ними
this.line.init(200, 1);


F_Flash 25.07.2006 12:24

Хороший вариант решения.

tov_diatel 25.07.2006 18:29

Оличный вариант!

tov_diatel 25.07.2006 20:46

Все смотрел на ету веревочку и не понимал вроде все класно, но чето не хватает.Не хватает энерции. Веревка четка возвращается в исходное положения без затухающих колебаний.Но это не проблемно переделать. А так еще раз повторюсь-круто!

etc 25.07.2006 21:51

Ну это уже вы сами сообразите

motor4ik 25.07.2006 21:57

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

etc 25.07.2006 22:28

gravity и есть "вертикальный ветер"

motor4ik 26.07.2006 00:05

хм, я думал это сила тяжести:away:

etc 26.07.2006 00:07

Она же сила тяжести

iNils 26.07.2006 00:10

А ветер ведь порывами дует :)

motor4ik 26.07.2006 00:16

вот вот все верно, так что я круто сделал, сила тяжести постоянная, а ветер вертикальный рнд сделал )))

iNils 26.07.2006 00:51

Осталось только сопротивление материала добавить, чтобы при много большой длине веревка рвалась от своего веса.

3dgod 20.11.2009 16:16

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

Груз выполнен в виде мувиклипа на сцене.

Я создаю сразу 8 веревок, с немного различающимеся параметрами, чтобы не одинаково "жили"

Код AS1/AS2:

//функция выборки случайного числа из диапазона
function Range (min:Number, max:Number):Number
{
        var randomNum:Number = Math.floor (Math.random () * (max - min + 1)) + min;
        return randomNum;
}
//создаю контейнеры для 8 линий, привязываю к каждой веревке груз
for (i = 1; i <= 8; i++)
{
        this.createEmptyMovieClip ("line" + i,_root.getNextHighestDepth ());
        _root["line" + i].letter = _root["letter_" + i];
}
//инициализация веревки
this.init = function (num, len, X, line, t)
{
        line.len = len;
        line.wind = 0;
        //таймер для колебаний
        line.t = t;
        //мультипликатор для затухания
        line.multi = 1;
        line.point = [];
        for (var i = 0; i < num; i++)
        {
                var t = new Object ();
                t.x = X;
                //помещаем все точки веревки вверх, чтобы веревка "упала"
                t.y = -200;
                line.point.push (t);
        }
};
 
//собственно "жизнь" веревки
for (j = 1; j <= 8; j++)
{
        this["line" + j].onEnterFrame = function ()
        {
                this.t += 0.1;
                //затухания
                this.multi *= 0.99;
                this.gravity = 20 + this.t;
                this.wind = Math.sin (this.t) * 6 * this.multi;
                //помещаем верхний конец в нужный "гвоздик" и фиксируем
                this.point[0].y = 0;
                this.clear ();
                this.lineStyle (0,0xD7E1EB,100);
                this.moveTo (this.point[0].x,this.point[0].y);
                for (var i = 1, len = this.point.length; i < len; i++)
                {
                        //[x1,y1] и [x2,y2] - координаты предыдущей и текущей точки соответственно
                        var x1 = this.point[i - 1].x, y1 = this.point[i - 1].y;
                        var x2 = this.point[i].x, y2 = this.point[i].y;
                        // xd и yd - разница расстояний между точками
                        var xd = x2 - x1 + this.wind;
                        var yd = y2 - y1 + this.gravity;
                        //dist - расстояние между точками
                        var dist = Math.sqrt (xd * xd + yd * yd);
                        //коррекция расстояния между точками до требуемого (через подобие)
                        this.point[i].x = x1 + (xd * (Math.cos (this.t * 1.3) * 1 * this.multi + this.len)) / dist;
                        this.point[i].y = y1 + (yd * (Math.sin (this.t * 1.3) * 1 * this.multi + this.len)) / dist;
                        this.lineTo (this.point[i].x,this.point[i].y);
                }
                //перемещаем груз к последней точке
                this.letter._x = this.point[this.point.length - 1].x;
                this.letter._y = this.point[this.point.length - 1].y;
        };
 
}


iflamberg 20.11.2009 16:30

23dgod: ничего нету. Функция init нигде не вызывается.


Часовой пояс GMT +4, время: 09:30.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.