Как правильно масштабировать повернутые объекты в Actionscript 3? - PullRequest
0 голосов
/ 17 марта 2010

Это, к сожалению, довольно сложный вопрос для объяснения, поэтому, пожалуйста, не расстраивайтесь из-за стены текста - это не просто так. ;)

Я работаю над менеджером преобразований для 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;

Это работает, когда объект не вращается. Однако, когда это так, упаковщик положения не будет вращаться, так как он является родителем оболочки вращения. Это заставит позиционер перемещаться влево по горизонтали, в то время как ширина объекта увеличивается по диагонали.

Надеюсь, в этом есть какой-то смысл, если нет, пожалуйста, скажите мне, и я постараюсь уточнить подробнее.

Теперь к вопросу: должен ли я использовать другой тип установки, систему или структуру? Должен ли я использовать матрицы, если да, как бы вы сохранили статическую ширину / высоту после поворота? Или как мне исправить мою текущую систему оболочки для масштабирования после поворота? Любая помощь приветствуется.

Ответы [ 2 ]

1 голос
/ 18 марта 2010

Похоже, вы должны использовать матрицу преобразования
взгляните на этот великий пост
http://gasi.ch/blog/zooming-in-flash-flex/

1 голос
/ 17 марта 2010

что по этому поводу:

positionWrapper.width -= diffX;
positionWrapper.x += diffX;

также вы можете выкинуть rotationWrapper и выполнить вращение на positionWrapper напрямую.

Кроме того, я предлагаю вам взглянуть на модификацию сенофула и модификаций сфирот .

edit: То, что вы в основном ищете, - это масштабное преобразование произвольным вектором с произвольным центром. с этим все остальное тривиально. для первой задачи: создайте матрицу M, которая перемещает центр в 0.0 и поворачивает вектор на ось x. concat M с x-шкалой по длине вектора и обратному к M и полученная матрица должна делать то, что вам нужно. конечно, вы можете рассчитать полученную матрицу с помощью ручки и бумаги напрямую, но этого должно быть достаточно

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