2012-03-19 18 views
5

मेरे पास समस्या है, यह है कि मुझे XYZ फिक्स्ड अक्ष रोटेशन से ज़ेड के बारे में यूलर रोटेशन में बदलने की आवश्यकता है, फिर एक्स ', फिर जेड' के लिए एक यूलर जेएक्सजेड रोटेशन से कनवर्ट करना।फिक्स्ड अक्ष XYZ रोटेशन

एक्स: X

Y:

यहाँ प्रासंगिक मैट्रिक्स हैं Y

जेड: Z

संयुक्त, RZ (साई) Ry के रूप में (PHI) आरएक्स (थीटा) = आरएक्सईज़ (थेटा, फाई, पीएसआई); वे दे:

Rxyz: Rxyz

और यूलर के विशिष्ट सम्मेलन के लिए रोटेशन मैट्रिक्स कोण मैं चाहता हूँ; यह है:

यूलर: Euler

तो मेरी प्रारंभिक योजना, मैट्रिक्स तत्वों की तुलना करें और कोण मैं चाहता था कि जिस तरह से निकालने के लिए किया गया था; मैं इस (अंत में वास्तविक वर्तमान कोड) के साथ आया था:

Code

लेकिन यह कई परिस्थितियों में काम नहीं करता। सबसे स्पष्ट जब कॉस (थेटा) कोस (फाई) == 1; तब से कोस (बीटा) = 1, और इसलिए पाप [बीटा] = 0. जहां कोड (बीटा) कोड में एस 2 है। ऐसा तब होता है जब कोस (थेटा) और कोस (phi) = +/- 1.

तो तुरंत मैं संभावित परिस्थितियों को रद्द कर सकता हूं;

जब थेटा या फाई = 0, 180, 360, 540, ..., तो कोस (थेटा), और कोस (फाई) +/- 1 हैं;

इसलिए मुझे इन मामलों के लिए इसे अलग-अलग करने की आवश्यकता है;

और मैं इस कोड के साथ समाप्त हो गया:

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(γ)}; 
} 

कहाँ 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); 
} 

eq सिर्फ परीक्षण के लिए संख्याओं की तुलना करने के लिए है, और आर चल Math.acos/Math.asin की श्रेणी से बाहर संख्या धक्का और मुझे NaN परिणाम देने बिंदु त्रुटियों को रोकने के लिए है;

(यानी हर अब और फिर मैं Math.acos (1.000000000000000004) या कुछ और के साथ पहुंचते हैं।)

कौन सा ध्यान में रखता है x और y चारों ओर चक्कर होने के 4 मामलों c2 == 1 छोड़ ।

लेकिन अब समस्या है जहां समस्या होती है;

मैंने जो कुछ भी किया है, वह मुझे समझ में आता है, लेकिन यह सही कोण नहीं देता है;

प्रत्येक जोड़ी में कुछ आउटपुट है, पहले थेटा फाई एससीआई कोण हैं, और प्रत्येक जोड़ी का दूसरा संबंधित अल्फा बीटा गामा लाइन है।राउंडिंग त्रुटियों की उपेक्षा कर, ऐसा लगता है की वजह से 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] 

मुझे लगता है कि यह द्वारा बंद कोण से कुछ हो रही है?

संपादित करें: math.asin और math.acos क्रमशः -पीआई/2 और पीआई/2 और 0 और पीआई के बीच मान लौटाते हैं। यह संदिग्ध नहीं है, इसलिए मुझे नहीं लगता कि समस्या यहां है। ऐसा लगता है कि मैं गणित गलत कहीं हो सकता है, लेकिन मैं अपने तर्क में एक छेद नहीं देख सकता ...

EDIT2: किसी को भी कैसे कैसे यूलर रोटेशन काम पता नहीं है के लिए, यह इस तरह है:

Euler Angles Gif

है, चारों ओर जेड घुमाएं, फिर नया एक्स धुरी के चारों ओर (एक्स ') फिर नए जेड चारों ओर' ' अक्ष।

+0

यूलर कोणों में 90 के दशक में अस्पष्टताएं होती हैं - मुझे लगता है कि 0/45/0 90/45/-90 के बराबर है यदि मैं आपकी अक्षों को सही ढंग से समझता हूं। –

+0

यूलर कोण ज़ेड के चारों ओर घूमते हैं, फिर एक्स ', फिर जेड', तो 0/45/0 एक्स अक्ष के बारे में 45 है, जबकि 90/45/-90 अक्ष को घुमाता है ताकि एक्स 'अक्ष समान हो वाई अक्ष। 90/45/-90 वाई के बारे में 45 का घूर्णन है। – will

उत्तर

1

मैंने इसे पूरी तरह से नहीं देखा है, लेकिन एक बात मैंने नोटिस की है: आप आर्कोस/आर्केसिन फ़ंक्शंस का उपयोग करते हैं जैसे कि कॉस/पाप बायक्टेक्टीव थे, बस अपना उलटा लेते थे। हालांकि, arccos लेने के दौरान, आर्क कार्यों में general solutions पर विचार करें। उदाहरण के लिए, जब cos y = x, तो वहाँ दो (अच्छी तरह से, असीम कई) समाधान हैं:

  • y = arccos x + 2kPI, जहां k element Z
  • y = 2PI - arccos x + 2kPI, कश्मीर ऊपर
k=-1 साथ

के रूप में, पिछले समीकरण को कम कर देता है

  • y = -arccos x

तो कुल मिलाकर, y = +- arccos x। यह अनिवार्य रूप से इस तथ्य को उबालता है कि cosx=0 पर अक्षीय सममित है। एक अनुरूप तर्क arcsin पर लागू होता है, (sin y = x के सामान्य समाधान में k=0 के साथ) y = PI - asin x के लिए अग्रणी

यह immediatelly अपने कोड लागू होता है। बयान γ = Math.acos(r(c3)); किसी भी तरह से खाते में साइन इन लेना चाहिए। मैं इस के साथ संघर्ष करता हूं, "गलत" समाधान को हल करने के लिए एक मानदंड होना चाहिए।

+0

मैंने यह भी देखा, हर बार एसीओएस/असिन का इस्तेमाल किया जाने पर गलत जवाब देने की परेशानी हालांकि मुश्किल लग रही थी - मैंने कल्पना की कि इसे एक छोटे से परीक्षण सूट को चलाने की आवश्यकता है 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

संबंधित मुद्दे