代码之家  ›  专栏  ›  技术社区  ›  Bradley Bossard

Actionscript中矩阵缩放/旋转的奇怪稳定性问题

  •  1
  • Bradley Bossard  · 技术社区  · 13 年前

    我有一个Flash应用程序,在那里我正在围绕_background:MovieClip(代表一本书的一页)的中心执行缩放和旋转操作。我在这个MC的GESTURE_ROTATE和GESTURE_SCALE事件上有一个简单的事件监听器,它们更新了一些变量currentRotation和currentScaleX,currentScaleY。然后,我在应用程序的ENTER_FRAME事件上有以下代码触发器。

    我遇到的问题是,当MC旋转超过大约60度或-60度的极限,或者稍微缩放并旋转时,MC开始振荡,最终失控旋转并离开屏幕。我试过几种方法来调试它,甚至试过Math.flooring currentRotationValue,并将currentScaleX/Y的值四舍五入到十分位(Math.floor(currentScale*10)/10),但这两种方法似乎都无法解决问题。我有点陷入困境,尽我所能进行了研究,但一无所获。有什么建议吗?对每一帧执行此操作可能有问题吗?

    private function renderPage(e:Event) {
        var matrix:Matrix = new Matrix();
    
        // Get dimension of current rectangle.
        var rect:Rectangle = _background.getBounds(_background.parent); 
    
        // Calculate the center.
        var centerX = rect.left + (rect.width/2);
        var centerY = rect.top + (rect.height/2);
    
        // Translating to the desired reference point.
        matrix.translate(-centerX, -centerY); 
    
        matrix.rotate(currentRotation / 180) * Math.PI);
        matrix.scale(currentScaleX, currentScaleY);
        matrix.translate(centerX, centerY); 
    
        _background.transform.matrix = matrix;
    }
    
    1 回复  |  直到 13 年前
        1
  •  0
  •   David Mear    13 年前

    我不确定你试图做出什么行为,但我认为问题在于 centerX centerY 定义的中间 _background 在里面 _background.parent 坐标空间。然后你正在翻译 matrix 因此 _背景 围绕值旋转 centerX, centerY ,但在 _背景 的坐标空间。

    假设你想要 _背景 要围绕屏幕上保持静止的点旋转,实际需要做的是使用两个不同的 Points :

    matrix.translate(-_rotateAroundPoint.x, -_rotateAroundPoint.y); 
    
    matrix.rotate(currentRotation / 180) * Math.PI);
    matrix.scale(currentScaleX, currentScaleY);
    
    matrix.translate(_centerOnPoint.x, _centerOnPoint.y); 
    

    哪里 _rotateAroundPoint 是围绕哪个点 _背景 应该上交 自身坐标空间 _centerOnPoint 是它应该转向的点 父母的 坐标空间。

    这两个值只需要在要平移时重新计算 _背景 ,而不是每一帧。例如:

    private var _rotateAroundPoint:Point = new Point(_background.width * 0.5, _background.height * 0.5);
    private var _centerOnPoint:Point = new Point(50, 50);
    
    private function renderPage(e:Event) {
        var matrix:Matrix = new Matrix();
    
        matrix.translate(-_rotateAroundPoint.x, -_rotateAroundPoint.y); 
    
        matrix.rotate((currentRotation / 180) * Math.PI);
        matrix.scale(currentScaleX, currentScaleY);
        matrix.translate(_centerOnPoint.x, _centerOnPoint.y); 
    
        _background.transform.matrix = matrix;
    }