Форум 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)
-   -   приближённый к реалистичному drag&drop фотографии (http://www.flasher.ru/forum/showthread.php?t=98592)

fljot 17.07.2007 03:17

приближённый к реалистичному drag&drop фотографии
 
привет. помогите пожалуйста с алгоритмом, что-то я завяз. может упёрся во что-то и ошибки в упор не вижу, бывает же такое.

отец iNils, надеюсь тебя это заинтересует и пособишь!

задача с точки зрения AS вроде незаковыристая, дело просто в алгоритме исполнения.
требуется: реализовать drag&drop приближённый к реалистичному миру. таскаем фотку(как по столу, прижав слегка и подняв мокрым пальцем=) ). берём за уголочек - "центр тяжести" на противоложном уголке и поворот осуществляется по полной программе(коэф. поворота 1). берём в центре - "центр тяжести" тут же, коэф поворота ноль(если точно в цетре схватить то типа не образуется крутящего момента). в промежуточных точках захвата - соответственно, тока коэф поворта(например) изменяется нелинейно чтоб меньше чувствовался жёсткий алгоритм.
вобщем что-то оно не так крутится как задумывалось.. главная неуверенность из-за осей x и y, которые во флеше смотрят не вправо и наверх, а вправо и вниз соотв.

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

ход реализации следующий: при зажатой кнопке и движении мыши:
- записываем координаты центра фоты (center{_x,_y})
- через точку захвата и коорд. центра вычисляем "центр тяжести" (rotation_center{_x,_y})
- вычисляем коэф. поворота (нормированный, квадрат удаления от цетра фоты. K_rotation)
- через прошлое и новое положение мыши вычисляем смещение мыши (hold_dx, hold_dy)
- вычисляем вектор локальной оси Х в абс. СК(система координат)(loc_Xaxis_x, loc_Xaxis_y)
- определяем угол между абс СК и локальной СК. через скалярное произведение абс. оси x (как ветор [1,0]) и ветора локальной X (вот тут я уже начинаю сомневаться)
- вычисляем относительное смешение вдоль локальных осей(в локальной СК) (loc_dx, loc_dy)

далее такая логика: за поворот отвечает смещение вдоль локальной оси Y (плюс ещё учёт коэф. поворота). за смещение фоты отвечает остальная часть вектора смещения(т.е. смещение вдоль локальной X и ещё остаток если коэф поворта был != 1)

- вычисляем угол поворта psi. из прямоугольного треугольника: противоположный нужному углу катет - это вектор смещения курсора в проекции на локальную ось Y, прилегающий катет - расстояние от точки захвата до центра тяжести
-поворачиваем на угол. вращение вокруг центра тяжести
-теперь смещаем фоту. на смещение вдоль локальной оси X и ещё остаточек от применения коэф. поворта
-записываем новые координаты мыши

исходник: http://***********/2691216

код:
Код:

function phys_drag() {
        hold_x = _root._xmouse; //координата x точки захвата
        hold_y = _root._ymouse; //координата y точки захвата
       
        this.onMouseMove = function() {
               
                //коориднаты центра объекта
                center = {_x: this._x, _y: this._y};

                //точка захвата: _root._xmouse, _root._ymouse
               
                //координаты цетра тяжести
                rotation_center = {_x: 2*center._x - _root._xmouse, _y: 2*center._y - _root._ymouse};
               
                //удаление от центра фоты (относительно 1/2 диагонали)
                d_from_center = Math.sqrt(((Math.pow((_root._xmouse - center._x),2) + Math.pow((_root._ymouse - center._y),2))) / _global.diagonal_length);
               
                //коэф поворота
                K_rotation = Math.pow(d_from_center, 2);
                               
                //смещение мыши(=точки захвата) в абс СК (система координат)
                _global.hold_dx = _root._xmouse - hold_x; _global.hold_dy = _root._ymouse - hold_y;
               
                //вектор локальной оси X (в абс координатах)
                loc_Xaxis_x = hold_x - center._x;        loc_Xaxis_y = hold_y - center._y;
               
                //определяем угол между абс СК и локальной СК. через скалярное произведение [1,0](=ось X) и локальной оси x
                cos_fi = loc_Xaxis_x/(Math.sqrt(loc_Xaxis_x*loc_Xaxis_x + loc_Xaxis_y*loc_Xaxis_y));
                fi = Math.acos(cos_fi); if (loc_Xaxis_y < 0) fi = 2*Math.PI - fi;
               
                //вычисляем относительное смешение вдоль локальных осей(в локальной СК)
                //т.е. переводим смещение  hold_dx и  hold_dy в локальную СК
                loc_dx = hold_dx*Math.cos(fi) - hold_dy*Math.sin(fi); //смещение по x в локальной
                loc_dy = hold_dx*Math.sin(fi) + hold_dy*Math.cos(fi); //смещение по y в локальной
               
                               
                //вычисляем угол поворта. из прямоугольного треугольника,
                //противоположный нужному углу катет - это вектор смещения курсора в проекции на локальную ось Y
                //прилегающий катет - расстояние от точки захвата до центра тяжести 
                //С УЧЁТОМ КОЭФ ПОВОРОТА
                rel_dy_x = loc_dy*Math.sin(-fi); //x-компонента проекции вектора смещения на локальную ось Y
                rel_dy_x_rot = rel_dy_x*K_rotation;  //x-компонента проекции вектора смещения на локальную ось Y С УЧЁТОМ КОЭФ ПОВОРОТА
                rel_dy_y = loc_dy*Math.cos(-fi);  //y-компонента проекции вектора смещения на локальную ось Y
                rel_dy_y_rot = rel_dy_y*K_rotation; //y-компонента проекции вектора смещения на локальную ось Y С УЧЁТОМ КОЭФ ПОВОРОТА
                tan_psi = Math.sqrt(Math.pow(rel_dy_x_rot,2) + Math.pow(rel_dy_y_rot,2))/(2*Math.sqrt(Math.pow(loc_Xaxis_x,2) + Math.pow(loc_Xaxis_y,2)));
                psi = Math.atan(tan_psi);
                if (loc_dy < 0) psi = -psi;
               
                //поворачиваем на угол. вращение вокруг центра тяжести
                this.rotation(psi, rotation_center._x, rotation_center._y);
               
                //вычисляем как надо сместить центр(переводим смещение в абс СК)
                //сместить его надо на смещение вдоль локальной оси X и на остаток от смещения вдоль локальной Y (из-за коэф поворота)
                //смещаем центр
                this._x += loc_dx*Math.cos(-fi) - loc_dy*(1-K_rotation)*Math.sin(-fi);
                this._y += loc_dx*Math.sin(-fi) + loc_dy*(1-K_rotation)*Math.cos(-fi);

               
                //записываем новые координаты мыши для вычисления
                //вектора смещения в следующей ветви
                hold_x = _root._xmouse;
                hold_y = _root._ymouse;
               
                updateAfterEvent();

                if (!this.hitTest(_root._xmouse, _root._ymouse, true))
                {
                        this.onMouseMove = null;
                        //trace('out!');
                }
               
        }
}

//поворачивает мувик относительно точки (pointx, pointy) на угол angle
//(положительное направление поворота по часовой)
MovieClip.prototype.rotation = function (angle, pointx, pointy) {
        var vector_x = this._x - pointx;
        var vector_y = this._y - pointy;
        var cos = Math.cos(angle);
        var sin = Math.sin(angle);
        var vector_rotate_x = (vector_x*cos - vector_y*sin);
        var vector_rotate_y = (vector_x*sin + vector_y*cos);
        this._x = vector_rotate_x + pointx;
        this._y = vector_rotate_y + pointy;
        this._rotation += angle*180/Math.PI;
};


iNils 17.07.2007 04:05

У меня нет детей, я точно помню :)
Немудрено, что вы запутались. Реализовать такой код линейно не лучший способ, а уж разбираться в нем совсем сложно. Поэтому лишь дам пару советов:
1. Логически отдельные операции лучше вынести в отдельные методы, спрятав ненужные хвосты.
2. Математическую модель отделить от мувиклипа вобще.
3. Вместо фото на этапе моделирования надо выводить вектора направлений. Это поможет лучше ориентироваться.

fljot 17.07.2007 04:12

iNils,
векторами тогда буду бить охъ.. пункт2 поясни пожалуйста, что здесь от чего отделить можно?

Kikasso 17.07.2007 04:19

У вас центр точно по центру?

iNils 17.07.2007 04:27

Цитата:

Сообщение от fljot
iNils,
векторами тогда буду бить охъ.. пункт2 поясни пожалуйста, что здесь от чего отделить можно?

В самом начале снять необходимые данные с "физического" объекта, передать их математической модели, обсчитать все, а потом применить обратно к объекту, тогда мыслей
Цитата:

главная неуверенность из-за осей x и y, которые во флеше смотрят не вправо и наверх, а вправо и вниз соотв.
точно не возникнет

etc 17.07.2007 10:15

http://etcs.ru/pre/Core/picture.swf
:D

(Какой-то треш давний, даже не доделан)

iNils 17.07.2007 11:19

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

etc 17.07.2007 11:34

Это просто потому что ты её в центре хватаешь. А в центре у неё центр тяжести, я не сделал мертвую зону…

fljot 17.07.2007 13:28

Цитата:

Сообщение от __etc
http://etcs.ru/pre/Core/picture.swf
:D

(Какой-то треш давний, даже не доделан)

вау супер! к этому тока фишку с коэф. поворота надо добавить!

могу я вас просить о коде касаемо этой части флешки? в личку отправил для чего)

etc 17.07.2007 13:52

Пожалуй, в данном случае я вам помочь ничем не могу.


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

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