Как получить визуальную ширину и высоту повернутого компонента? - PullRequest
2 голосов
/ 25 июля 2010

Я играю с кодом, подобным этому:

<s:Button id="test" label="test" transformX="{Math.floor(test.width/2)}" rotationY="20" x="20" y="20" />

Кнопка вращается вокруг оси Y, а ось вращения находится в середине кнопки.

Это будетсоздайте кнопку, которая выглядит примерно так:

альтернативный текст http://www.jeffryhouser.com/images/StackOverflowQuestions/StackOverflow3DWidthHeight.png

Повернутая кнопка визуально заполняет пространство, отличное от значений x, y, height и width, которые выверить.

Значение "A" на моем изображении - это высота кнопки.Но то, что я хочу использовать для целей расчета и размещения, это значение B.

Кроме того, я хотел бы выполнить аналогичные вычисления с шириной;получая ширину от верхнего правого угла до нижнего левого угла.

Как мне это сделать?


Я собрал образец , чтобы показатьразличные подходы для расчета этого, что люди предлагают.Исходный код также доступен .Ничто не работает так, как я ожидал.Например, поверните вращение Slider на 85. Кнопка фактически невидима, но все подходы все еще дают ей высоту и ширину.

Ответы [ 3 ]

1 голос
/ 26 июля 2010

getBounds (..) и getRect (..) должны быть методами для получения ширины и высоты преобразованных объектов.

Еще не пробовал их во Flex 4, но они всегда работали для меня во Flex 3.

1 голос
/ 25 июля 2010

Моя математика может быть немного ржавой, но вот как я могу найти ответ:

Вы бы вытянули прямоугольный треугольник от правого края кнопки до самой нижней точки имеющейся у вас диаграммы (A-B). Затем вы можете использовать закон синусов для получения трех углов: 90 ', 20' и 70 '(90 всегда будет там, а затем ваша переменная - 180 для третьего угла).

Вы можете использовать следующую формулу, чтобы найти ответ:

B = ((button.width * sin(button.rotationY)) / (sin(90 -button.rotationY)) + (button.height)
0 голосов
/ 08 августа 2010

Ответ был в одном из комментариев от Джеймса Уорда по этому вопросу и находится в этом сообщении в блоге .

Единственное, что не говорится в сообщении в блоге, это то, что вво многих случаях свойствоспектива проекции свойства преобразования в рассматриваемом классе будет нулевым.Ссылка на пример позаботилась об этом, установив для свойства maintainProjectionCenter значение true.Но вы также можете создать новый объектспективный проект, например:

object.transform.perspectiveProjection = new PerspectiveProjection();

Я обернул функцию из evtimmy в класс:

/**
 * DotComIt/Flextras 
 * Utils3D.as
 * Utils3D
 * jhouser
 * Aug 5, 2010
 */
package com.flextras.coverflow
{
    import flash.geom.Matrix3D;
    import flash.geom.PerspectiveProjection;
    import flash.geom.Rectangle;
    import flash.geom.Utils3D;
    import flash.geom.Vector3D;

    public class TransformUtilities
    {
        public function TransformUtilities()
        {
        }


    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  projectBounds
    //----------------------------------
    // info from 
    // http://evtimmy.com/2009/12/calculating-the-projected-bounds-using-utils3dprojectvector/

    /**
     * Method retrieved from  
     * http://evtimmy.com/2009/12/calculating-the-projected-bounds-using-utils3dprojectvector/
     * 
     * @param bounds:  The rectangle that makes up the object
     * @param matrix The 3D Matrix of the item
     * @param the projection of the item's parent.
     */
    public static function projectBounds(bounds:Rectangle,
                                         matrix:Matrix3D, 
                                         projection:PerspectiveProjection):Rectangle
    {
        // Setup the matrix
        var centerX:Number = projection.projectionCenter.x;
        var centerY:Number = projection.projectionCenter.y;
        matrix.appendTranslation(-centerX, -centerY, projection.focalLength);
        matrix.append(projection.toMatrix3D());

        // Project the corner points
        var pt1:Vector3D = new Vector3D(bounds.left, bounds.top, 0); 
        var pt2:Vector3D = new Vector3D(bounds.right, bounds.top, 0) 
        var pt3:Vector3D = new Vector3D(bounds.left, bounds.bottom, 0);
        var pt4:Vector3D = new Vector3D(bounds.right, bounds.bottom, 0);
        pt1 = Utils3D.projectVector(matrix, pt1);
        pt2 = Utils3D.projectVector(matrix, pt2);
        pt3 = Utils3D.projectVector(matrix, pt3);
        pt4 = Utils3D.projectVector(matrix, pt4);

        // Find the bounding box in 2D
        var maxX:Number = Math.max(Math.max(pt1.x, pt2.x), Math.max(pt3.x, pt4.x));
        var minX:Number = Math.min(Math.min(pt1.x, pt2.x), Math.min(pt3.x, pt4.x));
        var maxY:Number = Math.max(Math.max(pt1.y, pt2.y), Math.max(pt3.y, pt4.y));
        var minY:Number = Math.min(Math.min(pt1.y, pt2.y), Math.min(pt3.y, pt4.y));

        // Add back the projection center
        bounds.x = minX + centerX;
        bounds.y = minY + centerY;
        bounds.width = maxX - minX;
        bounds.height = maxY - minY;
        return bounds;
    }

    }

}

Хотя это ответ на мой вопросЯ не уверен, что это было решением моей проблемы.Спасибо всем!

...