Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   ActionScript 3.0 (http://www.flasher.ru/forum/forumdisplay.php?f=83)
-   -   поворот картинки по 90 градусам (http://www.flasher.ru/forum/showthread.php?t=152684)

in4core 21.03.2011 14:55

поворот картинки по 90 градусам
 
Есть контейнер, в нем постоянно находится только 1 чайлд - картинка. Картинка постоянно позиционируется по центру контейнера, когда с ней производят какие нибудь манипуляции. Есть задача, нужно по нажатию кнопки поворачивать эту саму картинку на += 90 градусов.

Вопрос такой, можно ли как то воспользоваться матрицами или еще чем, чтобы свернуть точку кручения в центр, тогда бы вопросов не было. Покажите пожалуйста пример, если можно. П.с. конструкция должна остаться такой КОнетйнер - внутри крутимая картинка. Координаты контейнера и применение к нему матриц недопустимо. Тоесть работать можно только с 1 чайлд-картинкой. И да пока не забыл, после применения кручения, нужно вернуть координату x и y в левый верхний угол соотв.

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

Zebestov 21.03.2011 15:17

Матрицами это делается в три хода: сдвинул > повернул > поставил на место

Александр Мостовой 21.03.2011 15:23

Да

http://help.adobe.com/en_US/FlashPla...ansformer.html

методы
rotateAroundExternalPoint
rotateAroundInternalPoint

Добавлено через 4 минуты
Поставить конейтер на начало его элементов можно при помощи getRect или getBounds и соответственно localToGlobal методов дисплэйобжекта

in4core 21.03.2011 16:32

@Александр Мостовой

А можете показать примерчик поворотов?

Допустим контейнер есть _cont , а картинка внутри _image . А то мне несовсем понятно как должны работать методы rotateAround...*

Wolsh 21.03.2011 16:42

Код AS3:

package ru.wolsh.display.utils 
{
    import flash.display.DisplayObject;
/* * * * * * * * * *
*                  *
*  @author wolsh  *
*                  *
*  v. 21.10.2010  *
*                  *
\* * * * * * * * * */

    public function centerRotate (object:DisplayObject, angle:Number) : void
    {
        var rad:Number = Math.PI / 180;
        // return object to default
        var currentAngle:Number = object.rotation * rad;
        object.rotation = 0;
        var oX:Number = object.width  / 2;
        var oY:Number = object.height / 2;
        var oS:Number = Math.sin(currentAngle);
        var oC:Number = 1 - Math.cos(currentAngle);
        object.x -= oX * oC + oY * oS;
        object.y -= oY * oC - oX * oS;
        // rotate object
        var r:Number = angle * rad;
        var s:Number = Math.sin(r);
        var c:Number = 1 - Math.cos(r);
        object.rotation = angle;
        object.x += oX * c + oY * s;
        object.y += oY * c - oX * s;
    }
 
}


in4core 21.03.2011 16:59

Wolsh спасибо большое. буду разбираться

Добавлено через 44 минуты
Wolsh что то косячит немного, или я не верно делаю

Код AS3:

function click(e:Event) {
 
centerRotate ( sprite , n )
 
n += 90
 
}

При первом повороте нормально, при втором уже нет, а при третьем вообще улетает неясно куда

Добавлено через 2 часа 9 минут
Решено. Вот аналог вашего класса
Код AS3:

private var _startPoint:Point = new Point(0,0);
public static function set externalPoint(p:Point) {
  _startPoint = p; // если крутим по центру передаем суда половину ширины и высоты
}
public static function rotateUserPoint (obj:DisplayObject , angle:int):void
                {
 
                        obj.transform.matrix = new Matrix();
 
                        var mat:Matrix = obj.transform.matrix;
 
                        MatrixTransformer.rotateAroundInternalPoint(mat, _startPoint.x, _startPoint.y, angle);
 
                        obj.transform.matrix = mat;
 
                }

Пример
Код AS3:

var n:int = 0;
RotationClass.externalPoint = new Point(sprite.width/2, sprite.height/2);
sprite.addEventListener(Event.ENTER_FRAME , go)
 
function go(e:Event) {
    RotationClass.rotateUserPoint ( e.currentTarget , n )
    n += 2;
}


Wolsh 21.03.2011 23:46

А, блин) Не с того проекта дернул класс, сорри. Там не было возврата в дефолт, это было в отдельном методе)).
Исправил код наверху на универсальный. Ну или, если нравятся матрицы, используйте их.

По Вашему коду - зачем статический метод для установки точки? Не лучше ли передавать точку в метод поворота, ведь она индивидуальна для каждого объекта, который Вы будете вращать? И почему set externalPoint(), если вращение методом rotateAroundInternalPoint() ? "Чтоб никто не догадался"?

in4core 21.03.2011 23:59

Wolsh ага чтоб никто не догадался)) Вопрос такой раз уж начал я делать все матрицами, как вернуть изначальную матрицу? Тоесть была матрица (1,0,0,1,100,100) допустим и угол был 0 градусов . Теперь я хочу повернуть объект на 90 градусов при этом после поворота сделать так, что бы матрица на объекте была такой, что поворот = 0, х и y координата = верхней левой точке?. Спасибо

Wolsh 22.03.2011 00:06

х и y координата всегда в верхней левой точке, выражаясь вашим языком.
То есть чтобы изменилось положение НАЧАЛА системы координат внутри спрайта относительно его содержимого (я правильно понял о чем речь?) надо переместить это содержимое в новые координаты. В случае детишек все решаемо математикой, но если это собственная графика спрайта (нарисованная в нем Графиксом), ее только перерисовывать.

in4core 22.03.2011 00:10

Wolsh я поясню. Вот был объект ( не нарисованный , а битмап) и стоял в 100-100. Я его повернул на 90 градусов. проверяю координаты пишет что x и y находятся теперь в правом верхнем углу, и это логично ведь прошел поворот и объект сменил матрицу. Вот я и спрашиваю как сделать, чтобы поворот прошел, но х и у снова находились в левом верхнем углу. Спасибо

Wolsh 22.03.2011 00:56

in4core я поясню. Во-первых, х и у находятся везде вокруг. Я даже не знаю, какие тяжелые наркотики надо употребить, чтобы все х и у вселенной собрались в одном углу. Вы говорите про начало системы координат объекта - точке, которая в самом объекте соответствует координатам (0, 0). Как бы Вы ни крутили объект, Вы крутите только его систему координат. А все содержимое объекта остается в этой его системе координат, на прежних местах. То, что хотите Вы - именно изменить положение и угол СОДЕРЖИМОГО. Ну подумайте сами - ведь если Вы повернете все, что в спрайте, на 90 градусов, не поворачивая и не смещая сам спрайт – это и будет то, чего Вы хотите. Точка (0,0) останется на своем месте, а все видимое повернется на нужный угол. Так?

in4core 22.03.2011 01:17

Хм. нет не так. Есть спрайт, в нем картинка. картинка на 100,100 . Создаем хелпер спрайт 10*10. Пробуем поставить его на координату картинка.x картинка.y - трейсим - выводит 100-100. Круто все верно. Теперь поворачиваем картинку в спрайте на 90 градусов. ( предположим что картинка была квадратной ) пробуем поместись хелпер на картинка.x картинка.y = выводит 200 - 100. Хотя левый угол картинки досих пор у нас в 100-100. А нам надо чтобы после трейса картинка.x картинка.y - мы увидили 100-100, что до по ворота, что после, из рассчета того, что точка поворота была в центре картинки. А сейчас до поворота центральной точки КВАДРАТНОЙ картинки, мы видим 100-100, после поворота 200-100, при следующем повороте 200-200, при следующем 100 - 200 - и при последнем УРА 100-100. а надо всегда 100-100 . При этом картинка будет не квадратной, тоесть точку привязки картинки нужно всегда помещать в левый верхний ВИДИМЫЙ для нас угол ( я понимаю, о чем вы говорите, что крутится вся система координат и левый верхний угол становится уже нижним и т.д. ) - всегда БЫЛ ВИДИМЫМ левым. Фу...много лишних слов, но надеюсь теперь более понятно

Wolsh 22.03.2011 02:00

Попробуйте перечитать то, что я написал выше.

tsarapkabel 22.03.2011 02:12

Цитата:

Сообщение от in4core (Сообщение 982609)
как сделать, чтобы поворот прошел, но х и у снова находились в левом верхнем углу

transformPoint + deltaTransformPoint

in4core 22.03.2011 02:16

Wolsh в том то и дело что я перечитал. Вы написали :
Цитата:

Ну подумайте сами - ведь если Вы повернете все, что в спрайте, на 90 градусов, не поворачивая и не смещая сам спрайт – это и будет то, чего Вы хотите. Точка (0,0) останется на своем месте, а все видимое повернется на нужный угол
С этим утверждением я согласен полностью. Но не знаю уже как объяснить повторю - спрайт не участвует в моем вопросе вообще. И не должен. он всегда остается на том месте на котором есть, поворачивается только объект внутри спрайта., но вопрос состоял в том, что бы все модификации были ТОЛЬКО с внутренним объектом, тоесть ПОВЕРНУВ систему координат внутреннего мне нужно вернуть для него прежную систему - ЛИШЬ для него именно, но при этом оставляя поворот. Это возможно сделать ?

Добавлено через 1 минуту
tsarapkabel да да читал, только не понял как использовать. Вы сами пробовали? покажите пожалуйста.

Wolsh 22.03.2011 10:16

Цитата:

Это возможно сделать ?
просил же перечитать:
Цитата:

В случае детишек все решаемо математикой, но если это собственная графика спрайта (нарисованная в нем Графиксом), ее только перерисовывать.
Вы можете в битмапе повернуть содержимое? А в шейпе? В текстфилде? Или Вы так и не поняли, что переместить А относительно В - то же самое, что переместить В относительно А? Можно "повернуть" битмапдату с шагом 90 градусов (при других углах ее пиксели уйдут в отрицательные координаты, что невозможно). Можно перерисовать графику шейпа или спрайта (я уже боюсь это слово использовать, похоже для Вас существует только один спрайт - Ваш контейнер) в новых координатах. Текст в текстфилде... даже не знаю, может в TLF его получится направить вертикальными строчками))) и можно посмещать отступами)) Но никакие матрицы тут не при делах - то, что нужно трансформировать - содержимое DisplayObject'а, а не DisplayObjectContainer'а. К этому содержимому просто нет доступа как к дисплейному объекту. Поэтому ответ, еще раз - в некоторых случаях можно эмулировать, если можно трансформировать содержимое. Если нельзя - то НЕТ.

cleptoman 22.03.2011 10:34

щас in4core что-нибудь придумает, спакуха! )

tsarapkabel 22.03.2011 17:53

Цитата:

Сообщение от in4core (Сообщение 982651)
Вы сами пробовали? покажите пожалуйста.

Можно на ты. Вечером покажу, если ещё будет актуально :)

in4core 22.03.2011 18:13

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

tsarapkabel 23.03.2011 02:32

Создаём спрайт.
По MOUSE_MOVE смотрим координаты нижней левой точки спрайта.
По клику выводится трейс этой координаты методом transformPoint.
Поворачивается спрайт.
Выводится второй трейс с уже изменёнными координатами.
И в завершении трейс дельты (на сколько изменились координаты).

Код AS3:

package {
 
        import flash.display.Sprite;
        import flash.events.MouseEvent;
        import flash.geom.Matrix;
        import flash.geom.Point;
        import flash.text.TextField;
        import flash.text.TextFieldAutoSize;
 
        public class DeltaPoint extends Sprite {
 
                private var t:TextField = new TextField();
                private var sprite:Sprite = new Sprite();
 
                public function DeltaPoint() {
 
                        t.border = true;
                        t.autoSize = TextFieldAutoSize.LEFT;
                        addChild(t);
 
                        stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
                        stage.addEventListener(MouseEvent.CLICK, onClick);
 
                        //var sprite:Sprite = new Sprite();
                        sprite.graphics.lineStyle (1, 0x0);
                        sprite.graphics.beginFill (0xCC99BB);
                        sprite.graphics.drawRect (0, 0, 150, 35);
                        sprite.mouseEnabled = false;
                        addChild (sprite);
                        sprite.x = sprite.y = 150;
                }
 
                private function onMove (event:MouseEvent):void {
                        //Для проверки координаты выводим в textField
                        t.text = event.localX + " " + event.localY;
                }
 
                private function onClick (event:MouseEvent):void {
                        var matrix:Matrix = sprite.transform.matrix;
 
                        //trace показывает, где в данный момент находится точка нижнего левого угла
                        trace (matrix.transformPoint (new Point (0, 34)))//(x=150, y=184)
 
                        var angle:Number = 90*Math.PI/180;
                        matrix.a = Math.cos(angle);
                        matrix.b = Math.sin(angle);
                        matrix.c = -Math.sin(angle);
                        matrix.d = Math.cos(angle);
                        sprite.transform.matrix = matrix;
 
                        //transformPoint показывает, куда сместилась та самая точка
                        trace (matrix.transformPoint (new Point (0, 34))); // (x=116, y=150)
 
                        //deltaTransformPoint показывает, на сколько изменились координаты
                        trace (matrix.deltaTransformPoint(new Point (0, 34))); // (x=-34, y=2.0818308014980413e-15)
                }
 
        }
}


in4core 23.03.2011 03:44

tsarapkabel. Особо не вникал, но мне кажется не то, что надо.

Надо приблизительно следующее :

Код AS3:

trace(sprite.x, sprite.y , sprite.rotation) // 100, 100 , 0
 
sprite.rotation = 90;
.....
functional code
....
 
trace(sprite.x, sprite.y , sprite.rotation) // 100, 100 , 90

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

Psycho Tiger 23.03.2011 17:22

in4core, вот Гейзенберг, Шрёдингер и прочие люди, создавшие квантовую механику были великими ученым. А ещё был такой Эйнштейн, и он ну никак не был согласен с квантовой теорией, она ему казалось абсурдной. И собрался он с ребятами-коллегами и придумали парадокс ЭПР. Можете почитать, кстати. И довольные ходили, опровергли как-будто бы всю теорию. Но вот в будущем люди провели эксперимент, который доказал правоту квантовой теории, а не Эйнштейна, который в это не верил. Кстати, Эйнштейн ещё постулировал что вообще любая информация не может передаваться быстрее скорости света. Этот эксперимент заставил его постулат выглядеть иначе: полезная информация не может передаваться быстрее скорости света.

Я к чему это всё? Даже Эйнштейн, который был в чем-то уверен ошибался, но его коллеги пролили свет. Вам пролили свет, что нативно во флеше это невозможно. Более того, в 9 из 10 случаев это бесполезно, как та информация, что передается быстрее скорости света. Вы не можете нарушить законы физики и Вы не можете нарушить законы нативного API. Вы страдаете фигнёй.
Я извиняюсь, что заговорил физическими аналогиями, но других вариантов объяснить Вам это я не вижу.


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

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