3D flex,围绕容器的随机点旋转(部分解决方案!)

时间:2009-03-09 16:55:39

标签: flex flash actionscript 3d

我正在尝试使用flash 10中的matrix3D功能来寻找旋转容器(或其他任何东西)的最佳方法。

我设法让一个容器围绕一个不是注册点的点旋转但是我只是通过关闭容器上的剪辑然后将内容放在除(0,0,0)以外的其他位置来管理它。这确实有效,但是当试图放置几个物品或者甚至需要移动旋转点时,它不是非常直观和糟糕。

使用matrix3D类似乎是要走的路,但我不确定究竟是怎么做的。

干杯

其他信息 - 如果我的容器位于舞台上的(0,0,0)并且我希望围绕容器的中间X坐标旋转,那么我将通过container.width / 2转换为X然后旋转并再次转换回来。这很好用。 但是,如果我的容器在(10,0,0)说,那么如果我翻译与上面相同并添加额外的10然后它不起作用。

Soloution(完全垃圾 - 请解释,如果可以的话) 如前所述,您需要翻译,旋转,然后进行翻译。我知道这一点,但从未奏效 但是看下面的解决方案,我不明白。 (面板是我正在旋转的对象,我将函数调用为())

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 个答案:

答案 0 :(得分:2)

旋转矩阵始终围绕原点旋转。

围绕任意点P旋转对象通常需要:

  1. -P
  2. 翻译对象
  3. 根据需要旋转对象
  4. P
  5. 翻译对象

答案 1 :(得分:1)

好的,解决方案是 -

1 - 创建自己的组件,其中包含原始X,Y,Z以及宽度和高度的变量。这些将用于协调以节省额外的矩阵操作。 E.G扩展Box类,只需将这些var添加到新类中。

2 - 向app添加组件,如下所示。 (原始值是因为实际的x,y,z等在旋转期间会发生变化,但你需要使用orig值来计算正确的旋转。

<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和amp; y(提供所有值的非硬编码)

答案 2 :(得分:0)

你考虑过简单地移动枢轴向量吗?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));