Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   Вращение изображения вокруг центра ViewPort (http://www.flasher.ru/forum/showthread.php?t=206131)

Sonet 14.01.2014 15:44

Вращение изображения вокруг центра ViewPort
 
Ситуация такова: есть изображение, которое лежит внутри контейнера фиксированного размера, оно может быть как больше так и меньше контейнера; у контейнра установлено свойство clipAndEnableScrolling, поэтому все, что за пределами контейнера невидимо. Надо уметь вращать изображение вокруг точки, которая является центром видимой зоны.

Код AS3:

                public static function rotateImageAroundCenterOfViewPort(image:Image, value:Number):void
                {
                        var bounds:Rectangle = image.getBounds(image.parent);
                        // Calculate rotation and shifts
                        var angle:Number = value - image.rotation;
                        var radians:Number = angle * (Math.PI / 180.0);
                        var shiftByX:Number = image.parent.width / 2 - bounds.x;
                        var shiftByY:Number = image.parent.height / 2 - bounds.y;
                        // Perform rotation
                        var matrix:Matrix = new Matrix();
                        matrix.translate(-shiftByX, -shiftByY);
                        matrix.rotate(radians);
                        matrix.translate(+shiftByX, +shiftByY);
                        matrix.concat(image.transform.matrix);
                        image.transform.matrix = matrix;
                }

Данная функция работает правильно только 1 раз (шаг вращения 90 градусов в любую сторону) и почему-то частенько не работает, если изображение имеет сдвиг или скейл. Что надо поменять, чтобы она работала всегда?

Akopalipsis 14.01.2014 15:55

Попробуйте вот так, point это точка во круг которой крутится объект.
Если работать не будет, хотя вроде должно, то на форуме много тем, Вы напишите если что, я попробую найти..
Аааа, я Вас вспомнил:) я тоже сейчас делаю трансформацию и мне кажется, что подход предложенный мной, может не подойти.
Код AS3:

private static var DEG_TO_RAD:Number = 3.1415926535897932 / 180;
public static function rotationPointMatrix(target:DisplayObject, angle:Number, point:Point = null):void
{
        var matrix:Matrix = target.transform.matrix;
        matrix.translate( -point.x, -point.y);
        matrix.rotate( -target.rotation * DEG_TO_RAD);
        matrix.rotate(angle * DEG_TO_RAD);
        matrix.translate(point.x, point.y);
        target.transform.matrix = matrix;
}


Sonet 14.01.2014 16:21

Пока не пробовал, но очень походе на мой способ. Мне кажется, что всю дело в:
Код AS3:

matrix.translate(+shiftByX, +shiftByY);

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

Isfet 14.01.2014 16:53

помещайте изображение в контейнер в координаты

Код AS3:

 img.x = -img.width*0.5;
 img.y = -img.height*0.5;

и вращайте сам контейнер

Sonet 14.01.2014 17:11

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

Akopalipsis 14.01.2014 17:28

Способ с -х-у может подойти, но обяжет все расчёты делать с минусами и не позволит вращать во круг произвольно взятой точки, что обязательно должно присутствовать в трансформе. я как сделаю, то покужу в Вашей теме, что у меня получилось, но пока я застрял на неопределённое время с рамкой, как в FS.

Sonet 14.01.2014 18:04

Код AS3:

public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
                {
                        trace("rotation Begin: x ", image.x, " y: ", image.y);
                        var bounds:Rectangle = image.getBounds(image.parent);
                        trace("rotation Begin: bounds.x ", bounds.x, " bounds.y: ", bounds.y);
                        // Calculate rotation and shifts
                        var angle:Number = value - Math.round(image.rotation);
                        var radians:Number = angle * (Math.PI / 180.0);
                        var shiftByX:Number;
                        var shiftByY:Number;
                        // Perform rotation
                        switch(Math.round(image.rotation) / 90 % 4)
                        {
                                case 0:
                                {
                                        shiftByX = image.parent.width / 2 - bounds.x;
                                        shiftByY = image.parent.height / 2 - bounds.y;
                                        break;
                                };
                                case 1:
                                {
                                        shiftByX = image.parent.height / 2 - bounds.y;
                                        shiftByY = bounds.width - (image.parent.width / 2 - bounds.x);
                                        break;
                                };
                                case -2:
                                case 2:
                                {
                                        shiftByX = bounds.width - (image.parent.width / 2 - bounds.x);
                                        shiftByY = bounds.height - (image.parent.height / 2 - bounds.y);
                                        break;
                                };
                                case -1:
                                {
                                        shiftByX = bounds.height - (image.parent.height / 2 - bounds.y);
                                        shiftByY = image.parent.width / 2 - bounds.x;
                                        break;
                                };
                                default:
                                {
                                        break;
                                }
                        }
                        var matrix:Matrix = new Matrix();
                        matrix.translate(-shiftByX, -shiftByY);
                        matrix.rotate(radians);
                        matrix.translate(+shiftByX, +shiftByY);
                        matrix.concat(image.transform.matrix);
                        image.transform.matrix = matrix;
                        trace("rotation End: x ", image.x, " y: ", image.y);
                        trace("rotation: xShift ", shiftByX, " yShift: ", shiftByY);
                }

Немного поизучал тему. Выяснил на практике, что смещение надо задавать от текущего положения top-left точки. А нахождение этой точки в свою очередь связано с углом поворота. Но вот незадача: в image.rotation накапливается погрешность, из-за чего через некоторое число поворотов метод начинает сбоить и появляется лишний угол поворота.

Akopalipsis 14.01.2014 18:19

Цитата:

в image.rotation накапливается погрешность, из-за чего через некоторое число поворотов метод начинает сбоить и появляется лишний угол поворота
Есть такое, но почему вы мой код не используете, там нет погрешностей.

Добавлено через 21 минуту
И погрешности не только в rotation накапливаются, это касается и x,y и может ещё чего.

Sonet 14.01.2014 20:38

Потому что, как и мой первый вариант, он вращает правильно всего 1 раз.
Код AS3:

                public static function rotateImageAroundCenterOfViewPort(image:Image, value:int):void
                {
                        var bounds:Rectangle = image.getBounds(image.parent);
                        trace("rotation Begin: bounds.x ", bounds.x, " bounds.y: ", bounds.y);
                        // Calculate rotation and shifts
                        var shiftByX:Number;
                        var shiftByY:Number;
                        // Perform rotation
                                        shiftByX = image.parent.width / 2 - bounds.x;
                                        shiftByY = image.parent.height / 2 - bounds.y;
                        var matrix:Matrix = image.transform.matrix;
                        matrix.translate( -shiftByX, -shiftByY);
                        matrix.rotate( -image.rotation * DEG_TO_RAD);
                        matrix.rotate(value * DEG_TO_RAD);
                        matrix.translate(shiftByX, shiftByY);
                        image.transform.matrix = matrix;
                }

Ыот во что он превратился у меня. Проблема в неверном вычислении точки поворота (т.е. с точки зрения смотрящего на экран - она верная, с точки зрения компонента - нет). Эту проблему я решил выше "свитчем", но возникла новая - с погрешностью.

Akopalipsis 14.01.2014 21:14

Sonet конечно я могу ошибаться, но я столько уже экспериментировал с трансформацией, что могу сказать - в коде нет ошибок. Вы можете просто включить его на EF и смотреть, как он крутится и крутится и не сбивается, даже если угол подавать вот 0,0000545454545 такими значениями.
Ошибка может крыться в том, что я пока тоже не делал, а именно, расчёт угла в зависимости от курсора.
Хотя сложного вроде не чего в этом нет.


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

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