代码之家  ›  专栏  ›  技术社区  ›  JeffryHouser

如何获取旋转组件的视觉宽度和高度?

  •  2
  • JeffryHouser  · 技术社区  · 14 年前

    我在玩这样的代码:

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

    按钮在Y轴上旋转,旋转轴位于按钮的中间。

    这将创建一个如下所示的按钮:

    alt text http://www.jeffryhouser.com/images/StackOverflowQuestions/StackOverflow3DWidthHeight.png

    旋转的按钮在视觉上填充的空间与X、Y、高度和宽度值不同。

    我的图像中的“A”值是按钮的高度。但是,我想用于计算和放置目的的是b值。

    另外,我想对宽度进行类似的计算;从右上角到左下角的宽度。

    我该怎么做?


    我把一个 sample 展示人们提出的各种计算方法。源代码也是 available . 没有什么比我想象的更有效了。例如,将旋转滑块转到85。这个按钮实际上是不可见的,但是所有的方法仍然给它高度和宽度。

    3 回复  |  直到 14 年前
        1
  •  1
  •   QueTwo    14 年前

    我的数学可能有点生疏,但我就是这样找到答案的:

    您可以将一个直角三角形从按钮的右边缘延伸到图的最底端(A-B)。然后你可以用正弦定律得到三个角度:90度,20度和70度(90度总是存在的,第三个角度是180度)。

    然后,您可以使用以下公式找到您的答案:

    B = ((button.width * sin(button.rotationY)) / (sin(90 -button.rotationY)) + (button.height)
    
        2
  •  1
  •   Gregor Kiddie    14 年前

    getbounds(..)和getrect(..)应该是获取转换对象的宽度和高度的方法。

    在flex 4中还没有尝试过,但在flex 3中他们总是为我工作。

        3
  •  0
  •   JeffryHouser    14 年前

    答案在詹姆斯·沃德对这个问题的评论中,就在这里。 blog post .

    博客文章没有说的一件事是,在许多情况下,所讨论的类上transform属性的透视投影属性将为空。链接到示例通过设置 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;
        }
    
        }
    
    }
    

    虽然这是我问题的答案,但我不确定这是否是解决我问题的办法。谢谢大家!