2012-03-19 2 views
5

문제는 내가 XYZ 고정 축 회전을 Z 축에 대한 Euler 회전으로 변환 한 다음 X ', Z'로 변환해야한다는 것입니다.오일러 ZXZ 회전에서 고정 축 XYZ 회전으로 변환

X : X

Y : 여기

은 해당 행렬이다 Y

Z : Z

결합 Rz가 (PSI) Ry가 아니라 (파이) 수신 (세타) = Rxyz (theta, phi, psi); 그들은 제공 :

Rxyz : Rxyz

그리고 회전 오일러의 특정 규칙에 대한 매트릭스 내가 원하는 각도를; 이는 다음과 같습니다

오일러 : Euler

그래서 내 초기 계획, 행렬 요소를 비교하고, 내가 그런 식으로 원하는 각도를 추출하는 것이 었습니다;

Code

을하지만이 여러 상황에서 작동하지 않습니다 :이 (마지막에 실제 현재 코드)를 내놓았다. 가장 확실한 것은 Cos (theta) Cos (phi) == 1; 그 이후 Cos (beta) = 1이고, 따라서 Sinβ는 0이다. 여기서 Sin (beta)는 코드에서 s2이다. 이것은 Cos (theta)와 cos (phi) = +/- 1 일 때만 발생합니다.

그래서 지금 당장 가능한 상황을 배제 할 수 있습니다. 030, 180, 360, 540, ..., Cos (theta) 및 Cos (phi)가 +/- 1 일 때, 0, 180, 360, 540,

그래서이 경우에만 다르게해야합니다.

와 나는이 코드를 사용하여 결국 :

public static double[] ZXZtoEuler(double θ, double φ, double ψ){ 

    θ *= Math.PI/180.0; 
    φ *= Math.PI/180.0; 
    ψ *= Math.PI/180.0; 

    double α = -1; 
    double β = -1; 
    double γ = -1; 

    double c2 = Math.cos(θ) * Math.cos(φ); 

    β = Math.acos(r(c2)); 

    if(eq(c2,1) || eq(c2,-1)){ 
     if(eq(Math.cos(θ),1)){ 
      if(eq(Math.cos(φ),1)){ 
       α = 0.0; 
       γ = ψ; 
      }else if(eq(Math.cos(φ),-1)){ 
       α = 0.0; 
       γ = Math.PI - ψ; 
      } 
     }else if(eq(Math.cos(θ),-1)){ 
      if(eq(Math.cos(φ),1)){ 
       α = 0.0; 
       γ = -ψ; 
      }else if(eq(Math.cos(φ),-1)){ 
       α = 0.0; 
       γ = ψ + Math.PI; 
      } 
     } 
    }else{ 

     //original way 

     double s2 = Math.sin(β); 

     double c3 = (Math.sin(θ) * Math.cos(φ))/ s2; 
     double s1 = (Math.sin(θ) * Math.sin(ψ) + Math.cos(θ) * Math.sin(φ) * Math.cos(ψ))/s2; 

     γ = Math.acos(r(c3)); 
     α = Math.asin(r(s1)); 

    } 

    α *= 180/Math.PI; 
    β *= 180/Math.PI; 
    γ *= 180/Math.PI; 

    return new double[] {r(α), r(β), r(γ)}; 
} 
연구와 EQ가 두 간단한 함수는

;

public static double r(double a){ 
    double prec = 1000000000.0; 
    return Math.round(a*prec)/prec; 
} 

static double thresh = 1E-4; 
public static boolean eq(double a, double b){ 
    return (Math.abs(a-b) < thresh); 
} 

당량 시험에 숫자를 비교하는 단지이며, r은 Math.acos/Math.asin의 범위를 벗어나는 숫자를 밀고 나에게 NaN의 결과를 제공 소수점 오류 부동 방지하는 것입니다;

(즉 땐 내가 Math.acos (1.000000000000000004) 또는 무언가로 끝날 것입니다.)

계정으로 C2 == 1을 남겨 x와 y의 주위에 회전을 갖는 4 개의 사례를 취

.

그러나 이제 문제가 발생합니다.

위의 모든 작업은 나에게 의미가 있지만 정확한 각도는 제공하지 않습니다.

출력은 각 쌍에서 첫 번째는 theta phi psi 각이고 각 쌍의 두 번째는 해당 알파 베타 감마 선입니다.반올림 오류를 무시 보인다 인해 Math.acos 및 Math.asin 작품은, 사람이 솔루션을 생각할 수있는 방법에 대한

[0.0, 0.0, 0.0] - correct! 
[0.0, 0.0, 0.0] 

[0.0, 0.0, 45.0] - correct! 
[0.0, 0.0, 45.0] 

[0.0, 0.0, 90.0] - correct! 
[0.0, 0.0, 90.0] 

[0.0, 0.0, 135.0] - correct! 
[0.0, 0.0, 135.0] 

[0.0, 0.0, 180.0] - correct 
[0.0, 0.0, 180.0] 

[0.0, 0.0, 225.0] - correct 
[0.0, 0.0, 225.0] 

[0.0, 0.0, 270.0] - correct 
[0.0, 0.0, 270.0] 

[0.0, 0.0, 315.0] - correct 
[0.0, 0.0, 315.0] 

[0.0, 45.0, 0.0] - incorrect: should be [90, 45, -90] 
[90.0, 44.999982, 90.0] 

[0.0, 45.0, 45.0] 
[45.000018, 44.999982, 90.0] 

[0.0, 45.0, 90.0] 
[0.0, 44.999982, 90.0] 

[0.0, 45.0, 135.0] 
[-45.000018, 44.999982, 90.0] 

[0.0, 45.0, 180.0] 
[-90.0, 44.999982, 90.0] 

[0.0, 45.0, 225.0] 
[-45.000018, 44.999982, 90.0] 

[0.0, 45.0, 270.0] 
[0.0, 44.999982, 90.0] 

[0.0, 45.0, 315.0] 
[45.000018, 44.999982, 90.0] 

[0.0, 90.0, 0.0] 
[90.0, 90.0, 90.0] 

[0.0, 90.0, 45.0] 
[45.000018, 90.0, 90.0] 

[0.0, 90.0, 90.0] 
[0.0, 90.0, 90.0] 

[0.0, 90.0, 135.0] 
[-45.000018, 90.0, 90.0] 

[0.0, 90.0, 180.0] 
[-90.0, 90.0, 90.0] 

[0.0, 90.0, 225.0] 
[-45.000018, 90.0, 90.0] 

내가 그것을 생각으로 떨어져 각도의 일부를 받고있다?

EDIT : math.asin 및 math.acos는 각각 -pi/2와 pi/2 및 0과 pi 사이의 값을 반환합니다. 이것은 애매하지 않기 때문에 문제가 여기에 있다고 생각하지 않습니다. 내가 잘못 어딘가에 수학을해야 할 수도 있습니다,하지만 난 내 추론에 구멍을 볼 수없는 것처럼 ... 보인다

EDIT2 : 오일러 회전 작동 방법을 알고하지 않습니다 어떻게 누구에게, 그것은이처럼 :

Euler Angles Gif

는 약 Z 회전 한 후, ' 축의 후 새로운 Z 주위 (새X 축 주위 X)'.

+0

오일러 각은 90 초에 모호성이 있습니다. 축을 올바르게 이해하면 0/45/0은 90/45/-90과 같다고 생각합니다. –

+0

오일러 각은 Z, X ', Z' '를 따라 회전하므로 0/45/0은 X 축에 대해 45이며 90/45/-90은 X'축이 Y 축. 90/45/-90은 Y 약 45 °의 회전입니다. – will

답변

1

나는 이것을 완전히 이해하지 못했지만주의해야 할 한 가지는 arccos/arcsin 함수를 cos/sin이 전체 효과가있는 것처럼 반올림 한 것으로 사용합니다. 그러나 arccos를 취할 때는 호 기능에 general solutions을 고려하십시오. 예를 들면, cos y = x 다음 두 (물론, 무한히 많은) 솔루션이있다 :

  • y = arccos x + 2kPI, k element Z
  • y = 2PI - arccos x + 2kPI, K 등 k=-1 함께

위의 마지막 식으로 줄여

  • y = -arccos x

따라서 y = +- arccos x입니다. 이것은 본질적으로 cos이 축 대칭 인 x=0이라는 사실로 귀결됩니다. 유사한 인수는

이 immediatelly 코드에 적용 (sin y = x의 일반적인 솔루션 k=0으로) y = PI - asin x로 이어지는 arcsin에 적용됩니다. 명세서 γ = Math.acos(r(c3));은 로그인을 고려해야합니다. 나는이 하나와 투쟁, 거기에 "잘못된"솔루션을 밖으로 정렬하는 기준이 있어야합니다.

+0

나는 이것도 알아 차렸다. acos/asin이 사용되었을 때마다 잘못된 답변을 제적하는 번거 로움이있었습니다. 나는 작은 시험 스위트를 실행해야 할 필요가 있다고 상상했습니다. +/- 모호성이 일으킬 수있는 4 가지 가능한 대답과 작동 한 대답을 선택합니다. 매번 테스트 스위트를 돌리는 것은 솔루션의 깔끔함을 다소 망치고 싶다. 나는 그다지 열광하지 않았다. – will

+0

나는 여기에도 질문을했다. http://math.stackexchange.com/questions/122162/convert-from-fixed-axis-xyz-rotations-to-euler-zxz-rotations 방금 ​​ZXZ를 사용하기로 결정했다. 오일러의 Z''X'Z 대신 회전. 그래도 여전히 이상하지 않습니다. – will

+0

그래서 나는 마침내이 모든 불행에 대해 약간의 독서를했습니다. 그것을하는 방법을 알아 내고 [여기] (http://math.stackexchange.com/a/637534/27211)에 대답했다. – will

관련 문제