Это, к сожалению, довольно сложный вопрос для объяснения, поэтому, пожалуйста, не расстраивайтесь из-за стены текста - это не просто так. ;)
Я работаю над менеджером преобразований для flash, написанным на ActionScript 3. Пользователи могут размещать объекты на экране, например, прямоугольник.
Этот прямоугольник затем можно выделить и преобразовать: перемещать, масштабировать или вращать.
Поскольку вспышка по умолчанию вращается вокруг верхней левой точки объекта, и я хочу, чтобы она вращалась вокруг центра, я создал настройку оболочки для каждого экранного объекта (например, прямоугольника).
Вот как настроены оболочки:
//the position wrapper makes sure that we do get the top left position when we access x and y
var positionWrapper:Sprite = new Sprite();
positionWrapper.x = renderObject.x;
positionWrapper.y = renderObject.y;
//set the render objects location to center at the rotation wrappers top left
renderObject.x = 0 - renderObject.width / 2;
renderObject.y = 0 - renderObject.height / 2;
//now create a rotation wrapper, at the center of the display object
var rotationWrapper:Sprite = new Sprite();
rotationWrapper.x = renderObject.width / 2;
rotationWrapper.y = renderObject.height / 2;
//put the rotation wrapper inside the position wrapper and the render object inside the rotation wrapper
positionWrapper.addChild(rotationWrapper);
rotationWrapper.addChild(renderObject);
Теперь, x и y объекта могут быть доступны и установлены напрямую: mainWrapper.x или mainWrapper.y. Вращение можно установить и получить к нему доступ от дочернего элемента этой главной оболочки: mainWrapper.getChildAt (0) .rotation. Наконец, ширина и высота экранного объекта могут быть восстановлены и установлены путем получения дочернего элемента оболочки вращения и прямого доступа к экранному объекту.
Пример того, как я к ним обращаюсь:
//get wrappers and render object
var positionWrapper:Sprite = currentSelection["render"];
var rotationWrapper:Sprite = positionWrapper.getChildAt(0) as Sprite;
var renderObject:DisplayObject = rotationWrapper.getChildAt(0);
Это прекрасно работает для всех начальных преобразований: перемещение, масштабирование и вращение.
Однако проблема возникает, когда вы сначала поворачиваете объект (например, на 45 градусов), а затем масштабируете его. Масштабированный объект теряет форму и не масштабируется должным образом.
Это, например, происходит при масштабировании влево. Масштабирование влево - это, в основном, добавление n ширины к объекту, а затем уменьшение координаты x в обертке позиции также на n:
renderObject.width -= diffX;
positionWrapper.x += diffX;
Это работает, когда объект не вращается. Однако, когда это так, упаковщик положения не будет вращаться, так как он является родителем оболочки вращения. Это заставит позиционер перемещаться влево по горизонтали, в то время как ширина объекта увеличивается по диагонали.
Надеюсь, в этом есть какой-то смысл, если нет, пожалуйста, скажите мне, и я постараюсь уточнить подробнее.
Теперь к вопросу: должен ли я использовать другой тип установки, систему или структуру? Должен ли я использовать матрицы, если да, как бы вы сохранили статическую ширину / высоту после поворота? Или как мне исправить мою текущую систему оболочки для масштабирования после поворота? Любая помощь приветствуется.