3D flex, вращение вокруг случайной точки для контейнера (с частичным решением!) - PullRequest
2 голосов
/ 09 марта 2009

Я пытаюсь найти лучший способ повернуть контейнер (или что-нибудь в этом роде), используя функции matrix3D во flash 10 для flex.

Мне удалось заставить контейнер вращаться вокруг точки, которая не является его точкой регистрации, но мне удалось это сделать, только отключив отсечение на контейнере, а затем поместив содержимое где-то, кроме (0,0,0) , Это работает, но не очень интуитивно понятно и отстой при попытке разместить несколько предметов или даже если вам нужно переместить точку вращения.

Кажется, стоит использовать класс matrix3D, но я точно не знаю, как именно.

Приветствия

Дополнительная информация - Если мой контейнер находится в точке (0,0,0) на сцене, и я хочу вращаться вокруг средней координаты X контейнера, тогда я перевожу на container.width / 2 для X, затем поворачиваю и снова переводю обратно. Это отлично работает. НО, если мой контейнер скажет в (10, 0, 0), тогда, если я переведу то же самое, что и выше, и добавлю дополнительные 10, то это не сработает.

Растворение (полная чушь - объясните, если можете) Как уже было предложено, вам нужно перевести, повернуть, затем -traslate. Я знал это, но это никогда не работало.
НО смотрите решение ниже, я не понимаю. (панель - это объект, который я вращаю, я вызываю функцию both ())

private function rotateOnly() : void {
        panel.transform.matrix3D.appendRotation(36, Vector3D.Y_AXIS);
}

private var valueToMove : Number = 300;
private var translateUpOrDown : Boolean = false;
private function translateOnly() : void {
    if(translateUpOrDown){
            panel.transform.matrix3D.appendTranslation(valueToMove, 0, 0);
    translateUpOrDown = false;
} else {
    panel.transform.matrix3D.appendTranslation(-valueToMove, -0,0);
    translateUpOrDown = true;
}
 }

 //I do not run both chunks of code here at once, this is only to show what I've tried   
 private function both() : void {
     //IF I call this function and call this chunk then the rotation works
        translateOnly();
        rotateOnly();
        translateOnly(); 


     //If I call this chunk which does the exact same as the above it does NOT work!!
        panel.transform.matrix3D.appendTranslation(valueToMove, 0,0);
panel.transform.matrix3D.appendRotation(36, Vector3D.Y_AXIS);
panel.transform.matrix3D.appendTranslation(-valueToMove, 0,0); 
 }

Ответы [ 3 ]

2 голосов
/ 09 марта 2009

Матрицы вращения всегда вращаются вокруг начала координат.

Вращение объекта вокруг произвольной точки P обычно требует:

  1. перевод объекта на -P
  2. вращение объекта по мере необходимости
  3. перевод объекта на P
1 голос
/ 11 марта 2009

ОК, решение будет -

1 - создайте свой собственный компонент с переменными для оригинальных X, Y, Z, ширины и высоты. Они будут использоваться для удобства, чтобы сохранить дополнительные матричные операции. E.G расширяет класс Box и просто добавляет эти var в новый класс.

2 - добавить компонент в приложение, как показано ниже. (Значения оригинала объясняются тем, что фактические значения x, y, z и т. д. будут меняться во время вращения, но вам необходимо ввести значения ориг. для вычисления правильного вращения.

<local:RotationContainer 
        id="movingBox" 
        width="50"
        origWidth="50"
        height="60"
        origHeight="60"
        x="80"
        origX="80"
        y="70"
        origY="70"
        z="0"
        origZ="0"
        enterFrame="rotateObject(event)"
        />

3 - используйте следующий код при вращении, вызовите указанное выше событие enterFrame

private var translateUpOrDown : Boolean = false;
        private function translateOnly(obj : Object, valueToMoveX : Number,  valueToMoveY : Number) : void {

            if(translateUpOrDown){
                obj.transform.matrix3D.appendTranslation(valueToMoveX, valueToMoveY, 0);
                translateUpOrDown = false;
            } else {
                obj.transform.matrix3D.appendTranslation(-valueToMoveX, -valueToMoveY, 0);
                translateUpOrDown = true;
            }
        }

        private function rotateOnly(obj : Object) : void {
            obj.transform.matrix3D.appendRotation(rotationAmount, Vector3D.Y_AXIS);
        }

        private function rotateObject(event : Event) : void {

            var offsetX : Number = (event.currentTarget.origWidth / 2) + event.currentTarget.origX;
            var offsetY : Number = (event.currentTarget.origHeight / 2) + event.currentTarget.origY;

            translateOnly(event.currentTarget, offsetX, offsetY);
            rotateOnly(event.currentTarget);
            translateOnly(event.currentTarget, offsetX, offsetY);
        }

4 - вот и все. Это будет вращаться вокруг центральной точки на оси Y. Измените значения смещения для разных точек вращения.

UPDATE Как уже указывалось, вам не нужно перемещать вызовы в отдельную функцию, но вам нужно будет использовать вышеуказанное, чтобы вы могли получить исходную ширину, высоту, x & y (при условии, что вы не жестко кодируете все значения)

0 голосов
/ 11 марта 2009

Рассматривали ли вы просто перемещение вектора разворота?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...