Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   Поворот объекта вокруг точки с помощью тригонометрических функций (http://www.flasher.ru/forum/showthread.php?t=175235)

-De- 15.02.2012 01:08

Ну в общем да, заговор, это твипсы. Т.е. реально object.x вы знаете с точностью до 0.05 только. Решение - хранить параллельно Point или что-то подобное, где будет более точное значение. Тут пацаны говорят что что-то куда-то возвращать надо, я этого не понял и у меня работает и так %) Я и собсно смещения не видел, если честно %) Но теоретически может быть вполне =) ну вот крутится, чо
Код AS3:

//если этот код кого-то научит плохому, то я не виноват. Нервных также просьба не читать.
public var spr:Sprite;
                public function Main():void
                {
                        //if (stage) init();
                        //else addEventListener(Event.ADDED_TO_STAGE, init);
 
                        //var obj:Object = { s:new Sprite(), coords:new Point() };
                        spr = new Sprite();
 
                        spr.graphics.lineStyle(0);
                        spr.graphics.drawEllipse( -10, -5, 20, 10);
 
                        spr.x = 100;
                        spr.y = 100;
                        addChild(spr);
 
 
                        addEventListener(Event.ENTER_FRAME, up);
                }
 
                public function up(e:Event):void {
                        pointRotate(spr, new Point(150, 250), 5.12345);
                }
 
                public static function pointRotate (object:DisplayObject, center:Point, angle:Number) : void
                {
                var r:Number = angle * Math.PI / 180;
                var s:Number = Math.sin(r);
                var c:Number = Math.cos(r);
                var dX:Number = object.x - center.x;
                var dY:Number = object.y - center.y;
 
 
                var rotDiff:Number = object.rotation;
                object.rotation += angle;
                rotDiff = object.rotation - rotDiff;
                object.x = center.x + dX * c - dY * s;
                object.y = center.y + dX * s + dY * c;
                trace(object.x, center.x + dX * c - dY * s);//feel the difference
                }

UPD: а, это наверное вечная тема про "смещение точки регистрации". Я бы использовал доп. матрицу, которая задает новую систему координат. Это в некотором роде аналог вставки во внешний контейнер. Ладно, раз влез блин, то вот...
Код AS3:

public var spr:Sprite;
                public var mInner:Matrix = new Matrix();//это наши внутренние координаты
                public var mOuter:Matrix = new Matrix();//это наши внешние координаты
                public function Main():void
                {
 
                        graphics.lineStyle(0);
                        graphics.drawCircle(200, 100, 0.5);//чтоб видеть вокруг чего крутимся
 
                        spr = new Sprite();
                        spr.graphics.lineStyle(0);
                        spr.graphics.drawEllipse( -10, -5, 20, 10);//точка регистрации в центре эллипса
 
                        spr.x = 200 - 10;
                        spr.y = 100 - 5;
                        addChild(spr);
 
                        mOuter = spr.transform.matrix;//изначально mOuter - трансформ обьекта, mInner - единичная
 
                        setRegPoint(200, 100);
 
                        //updateTransform();
 
                        addEventListener(Event.ENTER_FRAME, up);
                }
 
                public function setRegPoint(X:Number, Y:Number):void {//эта функция ставит опорку в нужную точку (графика при этом не смещается)
                        var dx:Number = X - mOuter.tx;
                        var dy:Number = Y - mOuter.ty;
                        var p:Point = new Point(dx, dy);
                        var m:Matrix = mOuter.clone();
                        m.invert();
                        m.tx = 0;
                        m.ty = 0;
                        p = m.transformPoint(p);
                        mInner.tx -= p.x;
                        mInner.ty -= p.y;
                        mOuter.tx = X;
                        mOuter.ty = Y;
                }
 
                public function updateTransform():void {//когда меняются матрицы надо вызвать эту функцию, чтоб она применила изменения к спрайту или что у вас там
                        var m:Matrix = mInner.clone();//лучше завести ещё одну постоянную матрицу, чтоб не выделять тут память динамически
                        m.concat(mOuter);
                        spr.transform.matrix = m;
                }
 
                public function up(e:Event):void {
                        pointRotate(5.12345);
                }
 
                public function pointRotate (angle:Number) : void
                {
                        angle *= Math.PI / 180;
                        var prevX:Number = mOuter.tx;
                        var prevY:Number = mOuter.ty;
                        mOuter.rotate(angle);
                        mOuter.tx = prevX;
                        mOuter.ty = prevY;//поворачиваем mOuter на angle не трогая её позицию
                        updateTransform();
                }


Den_root 15.02.2012 01:24

-De-
Как ни прискорбно, но смещение есть. Такое же как и в дрругих примерах.:(

Wolsh 15.02.2012 01:42

Я чето тоже не понял - rotDiff для чего, если он не используется в итоге?

expl 15.02.2012 01:43

Цитата:

Не, там предлагаются матрицы и какой то совершенно костыльный способ, а без них можно обойтись?
Хорошо, что Вас математики не слышат. Обозвать матрицы костылём!

Wolsh 15.02.2012 01:47

Здесь разделительное "и", если Вы не заметили. То есть матрицы И костыль – засовывание объекта в контейнер и поворот контейнера.

PlutDem 15.02.2012 22:58

-De- Сейчас если переместить объект, а потом повернуть, то он перемещается обратно в свои изначальные координаты. Можно ли этого избежать? Сейчас ваш способ ничем не отличается от №3+начальная матрица, только кода больше

-De- 15.02.2012 23:02

Чтобы переместить обьект надо сменить tx и/или ty у матрицы mOuter, а затем вызвать updateTransform(). Т.е. позиция обьекта - это не его x, y, а tx, ty матрицы mOuter. Наверное потому у вас возвращается.
№3 никак не меняет точку регистрации. Несколько разные задачи.

Wolsh 16.02.2012 00:22

Вложений: 1
Код AS3:

package  
{
    import flash.geom.Point;
    import flash.display.DisplayObject;
/* * * * * * * * * *
*                  *
*  @author wolsh  *
*                  *
\* * * * * * * * * */

 
    public function pointRotate(object:DisplayObject, center:Point, angle:Number) : void
    {
        // return to zero
        angle += object.rotation;
        var a0:Number = - object.rotation * Math.PI / 180;
        var s0:Number = Math.sin(a0);
        var c0:Number = Math.cos(a0);
        var dX0:Number = object.x - center.x;
        var dY0:Number = object.y - center.y;
 
        object.rotation = 0;
        object.x = Math.round(center.x + dX0 * c0 - dY0 * s0);
        object.y = Math.round(center.y + dX0 * s0 + dY0 * c0);
 
        // new rotation
        var r:Number = angle * Math.PI / 180;
        var s:Number = Math.sin(r);
        var c:Number = Math.cos(r);
        var dX:Number = object.x - center.x;
        var dY:Number = object.y - center.y;
 
        object.rotation += angle;
        object.x = center.x + dX * c - dY * s;
        object.y = center.y + dX * s + dY * c;
    }
 
}

CustomRotation.swf   (2.0 Кб)

Во вложении тестовая свфка просто.
Можно кликать и ставить точку, вокруг которой прямоугольник крутится.
Черная точка ставится в стейдже, а белая - внутри самого прямоугольника, чтобы наблюдать люфт.

TanaTiX 16.02.2012 00:34

Wolsh, можно создать простенькую игру - "Впиши вращающиеся фигуры в форму, меняя центр вращения/трансформаций";)

Wolsh 16.02.2012 00:35

да, я уже с полчасика поиграл)))


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

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