PDA

Просмотр полной версии : Масштабирование относительно поинта - почему смещается объект?


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

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
07.12.2009, 18:27
вы вращаете спрайт. можно к примеру, при его создании расчитывать чтобы его центр был центром содержимого.

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

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

Спасибо

bicubic_bublic
08.12.2009, 13:45
у вас анимированные картинки что ли?
или вы перемещаете картинку внутри контейнера?


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
у вас анимированные картинки что ли?
или вы перемещаете картинку внутри контейнера?


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

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

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



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 минут
Резюме: округлять надо ВСЕ. Хотя бы до сотых.