Форум 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=133523)

Vit025 07.12.2009 17:50

Масштабирование относительно поинта - почему смещается объект?
 
Доброго всем времени суток! Пытаюсь организовать масштабирование относительно центра через матрицу. Все хорошо, но объект смещается монемногу в сторону. В данном случае примерно 20 пихелей в лево в минуту :eek: Не подскажет ли кто-нибудь что у меня тут не так? Два дня уже убил :-(

Код AS3:

package {
 
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.geom.Point;
    import flash.geom.Rectangle;
 
    public class tester extends Sprite {
 
                private var test1:Sprite=new Sprite;
                private var test2:Sprite = new Sprite;
 
                public function tester():void {
 
                        getRectangle(test1,0xFF0000);
                        getRectangle(test2,0x00FF00);
                        test1.x=50;
                        test2.x=84;
                        test1.y=test2.y=20;
 
                        addChild(test1);
                        addChild(test2);
                        test2.addEventListener(Event.ENTER_FRAME,centerScale);
                        test1.scaleX=test1.scaleY=1.1;
 
                }
 
                private var cs:Number=1;
                private var csplus:Number=0.1;
 
                private function centerScale(e:Event):void {
                        var obj:Sprite = e.currentTarget as Sprite;
                        if(cs>=2) {
                                csplus=-.1;
                        }
                        if(cs<=0.2) {
                                csplus=.1;
                        }
                        cs+=csplus;
                        var point:Point=getRealCenter(obj);
                        trace(point);
                        var matr:Matrix = obj.transform.matrix;
                        var position:Point = new Point(matr.tx,matr.ty);
                        var scal:Point=new Point(matr.a,matr.d);
                                matr.identity();
                        var center:Point = matr.deltaTransformPoint(point);
                                matr.translate(-center.x,-center.y);
                                matr.scale(cs,cs);
                                matr.translate(center.x,center.y);
                                obj.transform.matrix=matr;
                                matr.identity();
                                obj.x=position.x-point.x*(cs-scal.x);
                                obj.y=position.y-point.y*(cs-scal.y);
                }
 
                public function getRealCenter(target:Sprite):Point {
                        var targetBounds:Rectangle = target.getBounds(target);
                        var matr:Matrix = new Matrix;
                                matr.translate(-targetBounds.x,-targetBounds.y);
                        var data:BitmapData = new BitmapData(targetBounds.width,targetBounds.height,true,0x00000000);
                                data.draw(target,matr);
                        var colorBounds:Rectangle = data.getColorBoundsRect(0xFFFFFFFF, 0x00000000, false);
                        var result:Point = new Point(colorBounds.x+colorBounds.width/2,colorBounds.y+colorBounds.height/2);
                        return result.add(new Point(targetBounds.x,targetBounds.y));
                }
 
                private function getRectangle(obj:Sprite,color:uint):void {
                        obj.graphics.clear();
                        obj.graphics.beginFill(color,1);
                        obj.graphics.drawRect(80,80,2,80);
                        obj.graphics.endFill();
                }
    }
}

Спасибо

bicubic_bublic 07.12.2009 18:08

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

Vit025 07.12.2009 18:10

Цитата:

Сообщение от bicubic_bublic (Сообщение 870845)
Происходит, видимо, из-за округления дробных чисел.. Ох вы себе и жизнь то усложнили в этом примере..

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

bicubic_bublic 07.12.2009 18:27

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

Vit025 07.12.2009 19:35

Мде... ну вот, собственно, и ответ. bicubic_bublic - низкий поклон :-)

Добавлено через 17 часов 56 минут
Увы :-( номер не прошел. Если объект после установки не изменяется, то все в порядке, а если перемещается или, тем более, размножается, то я все равно возвращаюсь к своей схеме и нарываюсь на смещение. Все сводится к изменению Registration Pointа. Есть какие нибудь идеи?

Спасибо

bicubic_bublic 08.12.2009 13:45

у вас анимированные картинки что ли?
или вы перемещаете картинку внутри контейнера?

Код AS3:

var bitmap:Bitmap = .... ; //картинка, которую нужно повращать
var bitmapContainer:Sprite = new Sprite(); //собственно контейнер
bitmapContainer.addChild(bitmap);
bitmap.x = -bitmapCenterX; //совмещаем центр контейнера с центром картинки
bitmap.y = -bitmapCenterY;
....
bitmapContainer.rotation = 45;
bitmapContainer.x = 100;
bitmapContainer.y = 100;


Vit025 08.12.2009 13:52

Цитата:

Сообщение от bicubic_bublic (Сообщение 871072)
у вас анимированные картинки что ли?
или вы перемещаете картинку внутри контейнера?

Код AS3:

var bitmap:Bitmap = .... ; //картинка, которую нужно повращать
var bitmapContainer:Sprite = new Sprite(); //собственно контейнер
bitmapContainer.addChild(bitmap);
bitmap.x = -bitmapCenterX; //совмещаем центр контейнера с центром картинки
bitmap.y = -bitmapCenterY;
....
bitmapContainer.rotation = 45;
bitmapContainer.x = 100;
bitmapContainer.y = 100;


В том то и дело, что пока ставил просто объект как Вы посоветовали, то все было нормально. Но объекты надо перемещать/вращать/масштабировать и по одному и по несколько (причем произвольное количество). Как тут с контейнерами все сложить - ума не приложу. Например если у меня 5 объектов, а масштабировать надо любые 3 из них (причем вокруг центра между ними) то я опять возвращаюсь к тому, с чего начал. И вроде бы мой вариант работает, но это смещение :eek: ...

bicubic_bublic 08.12.2009 13:57

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

Vit025 08.12.2009 14:01

Цитата:

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

Пробовал. Становится только хуже т.к. точность то уменьшается.

Добавлено через 38 минут
Мде... похоже это Проблема... Попробовал MatrixTransformer (из fl.motion.MatrixTransformer)- тот же результат! Объект смещается!



Код AS3:

package {
 
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.geom.Matrix;
    import flash.geom.Point;
 
    import fl.motion.MatrixTransformer;
 
    public class tester extends Sprite {
 
                private var test1:Sprite=new Sprite;
                private var test2:Sprite = new Sprite;
 
                public function tester():void {
 
                        getRectangle(test1,0xFF0000);
                        getRectangle(test2,0x00FF00);
                        test1.x=50;
                        test2.x=84;
                        test1.y=test2.y=20;
 
                        addChild(test1);
                        addChild(test2);
                        test2.addEventListener(Event.ENTER_FRAME,rotateByTransformMatrix);
                }
 
                private function rotateByTransformMatrix(e:Event):void {
                        var obj:Sprite = e.currentTarget as Sprite;
                        var matr:Matrix = obj.transform.matrix;
                        MatrixTransformer.rotateAroundInternalPoint(matr,81,120,1);
                        obj.transform.matrix=matr;
                }
 
                private function getRectangle(obj:Sprite,color:uint):void {
                        obj.graphics.clear();
                        obj.graphics.beginFill(color,1);
                        obj.graphics.drawRect(80,80,2,80);
                        obj.graphics.endFill();
                }
    }
}

Добавлено через 2 часа 57 минут
Резюме: округлять надо ВСЕ. Хотя бы до сотых.


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

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