3D 플렉스, 컨테이너의 임의 지점을 중심으로 회전(부분 솔루션 포함!)

StackOverflow https://stackoverflow.com/questions/627087

문제

저는 Flex용 Flash 10의 Matrix3D 기능을 사용하여 컨테이너(또는 그와 관련된 모든 것)를 회전하는 가장 좋은 방법을 찾으려고 노력하고 있습니다.

컨테이너가 등록 포인트가 아닌 지점을 중심으로 회전하도록 관리했지만 컨테이너의 클리핑을 끄고 내용을 (0,0,0)이 아닌 다른 위치에 배치하는 방식으로만 이를 관리했습니다.이것은 작동하지만 매우 직관적이지 않고 여러 항목을 배치하려고 할 때나 회전 지점을 이동해야 하는 경우에도 짜증납니다.

Matrix3D 클래스를 사용하는 것이 좋은 방법인 것 같지만 정확히 어떻게 사용하는지는 잘 모르겠습니다.

건배

추가 정보 - 내 컨테이너가 무대의 (0,0,0)에 있고 컨테이너의 중간 x 코디를 회전시키고 싶다면 컨테이너로 번역 한 다음 x의 경우 Width/2로 번역 한 다음 다시 회전하고 다시 번역합니다.이것은 잘 작동합니다.그러나 내 컨테이너가 (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); 
 }
도움이 되었습니까?

해결책 2

좋습니다. 해결책은 다음과 같습니다.

1 - 원본 X, Y, Z 및 너비와 높이에 대한 변수를 사용하여 고유한 구성 요소를 만듭니다.이는 추가 행렬 연산을 절약하기 위한 편의를 위해 사용됩니다.예를 들어 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축의 중심점을 중심으로 회전합니다.다양한 회전 지점의 오프셋 값을 변경합니다.

지적대로 업데이트 호출을 별도의 함수로 옮길 필요는 없지만 원래 너비, 높이, X & Y (하드 코딩하지 않으면 모든 값을 제공 함)를 얻을 수 있도록 위의 내용을 사용해야합니다.

다른 팁

회전 행렬은 항상 원점을 중심으로 회전합니다.

임의의 점을 중심으로 객체 회전 P 일반적으로 다음이 필요합니다.

  1. 객체의 번역 -P
  2. 필요에 따라 객체 회전
  3. 객체의 번역 P

단순히 피벗 벡터를 이동하는 것을 고려해 보셨나요?

var matrix:Matrix3d = new Matrix3d();
matrix.appendRotation(degrees, axis, new Vector3d(container.width/2,container.height/2,0));
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top