2011-12-29 14 views
17

पर बनाने के लिए एक नया सीएमटीटीएटी रेफरेंस फ्रेम कैसे बनाया जाए, मैं डिवाइस मोशन मैनेजर रेफरेंस फ्रेम (जीरो के लिए) को बदलने में सक्षम होना चाहता हूं ताकि मेरे पास वाई अक्ष पर मेरा गुरुत्वाकर्षण वेक्टर हो।गुरुत्वाकर्षण को वाई अक्ष

आमतौर पर जब आप डिवाइस मोशन मैनेजर अपडेट शुरू करते हैं तो आपके पास केवल गुरुत्वाकर्षण के साथ गठबंधन किए गए फोन का z अक्ष होगा।

आप एक्स अक्ष को चुंबकीय या सही उत्तर ध्रुव के साथ गठबंधन करने के लिए मैग्नेटोमीटर का उपयोग करने के लिए इसे बदल सकते हैं। इसके साथ में मेरा एक्स अक्ष पॉइंटिंग उत्तर है और मेरा जेड अक्ष नीचे इशारा करता है।

मैं क्या करना चाहता हूं मेरे वाई अक्ष (ऋणात्मक) को इंगित करना है (ताकि यह गुरुत्वाकर्षण के साथ गठबंधन हो) और मेरे एक्स अक्ष भी सही चुंबकीय ध्रुव को इंगित कर सकें।

परिणाम मैं चाहता हूं कि जब मेरा फोन अभी भी लंबवत (चित्र) अभिविन्यास में खड़ा हो, तो फोन का अधिकार उत्तर ध्रुव पर गठबंधन किया जाएगा और मेरे सभी रीडिंग (रोल, पिच, यॉ) के रूप में पढ़ा जाएगा 0. फिर इसके साथ यदि मैं अपने अक्ष को एक्स अक्ष पर घुमाता हूं तो पिच बदल जाएगा, और यदि मैं वाई अक्ष के चारों ओर घूमता हूं तो yaw बदल जाएगा।

अब तक मुझे पता है कि मैं अपने स्वयं के संदर्भ फ्रेम को सेट कर सकता हूं यदि मैं पहले से संग्रहीत रवैया के विपरीत से गुणा करता हूं, (जैसे मैं इस फोन को इस अभिविन्यास में मैन्युअल रूप से सेट कर सकता हूं, उस दृष्टिकोण को बचा सकता हूं और बस नए गुणा को बढ़ाता हूं इस संग्रहित के विपरीत से रवैया और मेरे सभी रीडिंग बिल्कुल वही होंगे जो मैं चाहता हूं)।

लेकिन इसे मैन्युअल रूप से सेट करना एक विकल्प नहीं है, तो मैं इसे प्रोग्रामिक रूप से कैसे बना सकता हूं?

मुझे नहीं लगता कि मेरा खुद का रवैया संदर्भ फ्रेम बनाने के लिए कोई फ़ंक्शन है, या यदि कम से कम एक रोटेशन मैट्रिक्स द्वारा रवैया को गुणा करने के लिए कोई फ़ंक्शन था तो मैं शायद इसे हल कर सकता था। (क्योंकि मैं पिच में 90 डिग्री परिवर्तन से सभी दृष्टिकोण को गुणा करता हूं)।

मुझे आशा है कि मैं अपने आप को स्पष्ट रूप से बताया गया है,

मैं किसी भी सुझाव की सराहना करेंगे। धन्यवाद

पीडी: ये iPhone अभिविन्यास निर्देशांक हैं:

enter image description here

+0

क्या आप जानते हैं कि आईओएस 4 पर सही उत्तर के सापेक्ष रवैया कैसे लेना है? आईओएस 5 के लिए इसके लिए अच्छी विधियां हैं। – vale4674

+0

कोई खेद नहीं है, इसलिए मैं अपना खुद का संदर्भ दृष्टिकोण क्यों नहीं बना सकता ... – Pochi

+0

इस तरह की सामग्री के लिए कोई अच्छी सामग्री ऑनलाइन नहीं है .. बहुत बुरा। – vale4674

उत्तर

-1

I hope this will help you

आप संदर्भ एक CMAttitude उदाहरण के द्वारा प्रयोग किया फ्रेम बदल सकते हैं। ऐसा करने के लिए, उस रवैया ऑब्जेक्ट को कैश करें जिसमें उस संदर्भ फ्रेम को शामिल किया गया है और गुणा करने के लिए तर्क के रूप में ByInverseOfAttitude:। संदेश प्राप्त करने वाला रवैया तर्क उस संदर्भ फ्रेम से रवैये में परिवर्तन का प्रतिनिधित्व करने के लिए बदला जाता है।

यह देखने के लिए कि यह कैसे उपयोगी हो सकता है, बेसबॉल गेम पर विचार करें जहां उपयोगकर्ता डिवाइस को स्विंग करने के लिए घुमाता है। आम तौर पर, एक पिच की शुरुआत में, बल्ले कुछ आराम अभिविन्यास पर होगा। इसके बाद, बल्ले को एक अभिविन्यास पर प्रस्तुत किया जाएगा, यह निर्धारित करता है कि डिवाइस के रवैये को कैसे पिच की शुरुआत में बदल दिया गया था।

-(void) startPitch { 

// referenceAttitude is an instance variable 

referenceAttitude = [motionManager.deviceMotion.attitude retain]; 

}

- (void)drawView { 

CMAttitude *currentAttitude = motionManager.deviceMotion.attitude; 

[currentAttitude multiplyByInverseOfAttitude: referenceAttitude]; 

// render bat using currentAttitude ..... 

[self updateModelsWithAttitude:currentAttitude]; 

[renderer render]; 

}

नीचे में अधिक देखो के लिए लिंक है कि एक ही बात यह है कि आप चाहते हैं।

http://db-in.com/blog/2011/04/cameras-on-opengl-es-2-x/

+2

यह समस्या का समाधान नहीं करता है। यह सेब देव दस्तावेजों से है, निश्चित रूप से मैं उस संदर्भ रवैये को कैश कर सकता हूं लेकिन यदि आप विधि की जांच करते हैं तो इसे डिवाइस गति का उपयोग करके वर्तमान दृष्टिकोण को कॉल करने के बाद रनटाइम की आवश्यकता होती है, मैं जानना चाहता हूं कि अपना खुद का रवैया संदर्भ फ्रेम कैसे बनाएं ताकि मैं इसे एक अलग अभिविन्यास में "शुरू" कर सकता हूं। – Pochi

+1

यह किसी भी एट्रिब्यूशन के बिना ऐप्पल की वेबसाइट से चोरी की गई है। – aledalgrande

4

छद्म कोड:

  1. शुरू डिवाइस गति अपडेट
  2. पृष्ठभूमि में एक कैमरा पूर्वावलोकन शुरू;)
  3. कब्जा वर्तमान गुरुत्वाकर्षण एक CMAcceleration के रूप में उपकरण से पढ़ने .. एक बार जब आप गुरुत्वाकर्षण को स्थानीय चर में स्टोर करते हैं।
  4. फिर आपको 2 वैक्टर लेना होगा और कोण के बीच कोण प्राप्त करना होगा, इस मामले में डिवाइस गुरुत्वाकर्षण (0,0, -1) और असली गुरुत्वाकर्षण वेक्टर ...
  5. हम फिर थेटा को चालू करते हैं thetaPrime ... एक कि CoreMotion संदर्भ उन्मुखीकरण
  6. सेटअप चेतन करने के लिए ....
  7. एनीमेशन दौरान motionManager के rotationMatrix deviceMotion संपत्ति का प्रतिलोम प्राप्त एक टाइमर से मेल खाता बदलने।
  8. यहाँ उपकरण के वर्तमान रवैया (विचलन, पिच, Eulerian मोड या उपकरणों चौका रोटेशन में रोल ... 3 अलग अलग तरीकों से एक ही बात मूल रूप से कहने के लिए)

प्रतिबिंबित करने के लिए सही क्रम में रूपांतरण लागू करें कोड है:

- (void) initMotionCapture 
{ 
    firstGravityReading = NO; 
    referenceAttitude = nil; 

    if (motionManager == nil) 
    { 
     self.motionManager = [CMMotionManager new]; 
    } 
    motionManager.deviceMotionUpdateInterval = 0.01; 
    self.gravityTimer = [NSTimer scheduledTimerWithTimeInterval:1/60.0 target:self selector:@selector(getFirstGravityReading) userInfo:nil repeats:YES]; 
} 


- (void) getFirstGravityReading 
{ 
    CMAcceleration currentGravity; 

    CMDeviceMotion *dm = motionManager.deviceMotion; 
    referenceAttitude = dm.attitude; 
    currentGravity = dm.gravity; 

    [motionManager startDeviceMotionUpdates]; 

    if (currentGravity.x !=0 && currentGravity.y !=0 && currentGravity.z !=0) 
    { 
     NSLog(@"Gravity = (%f,%f,%f)", currentGravity.x, currentGravity.y, currentGravity.z); 

     firstGravityReading = YES; 
     [gravityTimer invalidate]; 
     self.gravityTimer = nil; 
     [self setupCompass]; 
    } 
} 

- (void) setupCompass 
{ 
    //Draw your cube... I am using a quartz 3D perspective hack! 
    CATransform3D initialTransform = perspectiveTransformedLayer.sublayerTransform; 
    initialTransform.m34 = 1.0/-10000; 


    //HERE IS WHAT YOU GUYS NEED... the vector equations! 
    NSLog(@"Gravity = (%f,%f,%f)", currentGravity.x, currentGravity.y, currentGravity.z); 

    //we have current gravity vector and our device gravity vector of (0, 0, -1) 
    // get the dot product 
    float dotProduct = currentGravity.x*0 + currentGravity.y*0 + currentGravity.z*-1; 
    float innerMagnitudeProduct = currentGravity.x*currentGravity.x + currentGravity.y + currentGravity.y + currentGravity.z*currentGravity.z; 
    float magnitudeCurrentGravity = sqrt(innerMagnitudeProduct); 
    float magnitudeDeviceVector = 1; //since (0,0,-1) computes to: 0*0 + 0*0 + -1*-1 = 1 

    thetaOffset = acos(dotProduct/(magnitudeCurrentGravity*magnitudeDeviceVector)); 
    NSLog(@"theta(degrees) = %f", thetaOffset*180.0/M_PI); 

    //Now we have the device angle to the gravity vector (0,0,-1) 
    //We must transform these coordinates to match our 
    //device's attitude by transforming to theta prime 
    float theta_deg = thetaOffset*180.0/M_PI; 
    float thetaPrime_deg = -theta_deg + 90; // ThetaPrime = -Theta + 90 <==> y=mx+b 

    NSLog(@"thetaPrime(degrees) = %f", thetaOffset*180.0/M_PI); 

    deviceOffsetRotation = CATransform3DMakeRotation((thetaPrime_deg) * M_PI/180.0, 1, 0, 0); 
    initialTransform = CATransform3DConcat(deviceOffsetRotation, initialTransform); 

    perspectiveTransformedLayer.sublayerTransform = initialTransform; 

    self.animationTimer = [NSTimer scheduledTimerWithTimeInterval:1/60.0 target:self selector:@selector(tick) userInfo:nil repeats:YES]; 

} 

- (void) tick 
{ 
    CMRotationMatrix rotation; 

    CMDeviceMotion *deviceMotion = motionManager.deviceMotion; 
    CMAttitude *attitude = deviceMotion.attitude; 

    if (referenceAttitude != nil) 
    { 
     [attitude multiplyByInverseOfAttitude:referenceAttitude]; 
    } 
    rotation = attitude.rotationMatrix; 

    CATransform3D rotationalTransform = perspectiveTransformedLayer.sublayerTransform; 

    //inverse (or called the transpose) of the attitude.rotationalMatrix 
    rotationalTransform.m11 = rotation.m11; 
    rotationalTransform.m12 = rotation.m21; 
    rotationalTransform.m13 = rotation.m31; 

    rotationalTransform.m21 = rotation.m12; 
    rotationalTransform.m22 = rotation.m22; 
    rotationalTransform.m23 = rotation.m32; 

    rotationalTransform.m31 = rotation.m13; 
    rotationalTransform.m32 = rotation.m23; 
    rotationalTransform.m33 = rotation.m33; 

    rotationalTransform = CATransform3DConcat(deviceOffsetRotation, rotationalTransform); 
    rotationalTransform = CATransform3DConcat(rotationalTransform, CATransform3DMakeScale(1.0, -1.0, 1.0)); 


    perspectiveTransformedLayer.sublayerTransform = rotationalTransform; 
} 
+0

क्या यह सही है, दूसरे शब्दों में: जब ऐप शुरू होता है, तो सीएम संदर्भ फ्रेम आईफोन के वर्तमान दृष्टिकोण के अनुसार सेट होता है। यानी रोल, यॉ और पिच के मान एक ही कोण पर फोन होने पर समान होने की गारंटी नहीं है। हालांकि, कच्चे एक्सेलेरोमीटर डेटा को पढ़कर, आप एक ट्रांसफॉर्म प्राप्त कर सकते हैं जो डिवाइसमोशन.एट्यूड्यूड प्रॉपर्टी पर लागू होने पर गुरुत्वाकर्षण के संबंध में डिवाइस का वास्तविक अभिविन्यास देता है। –

+0

वेक्टरों में कम से कम उन लोगों के लिए, यह आरंभिक गुरुत्वाकर्षण को तीन यूलर कोणों के सेट में बदलने के बराबर होना चाहिए - उदाहरण के लिए <संदर्भ के आपकी पसंद की तुलना में डिवाइस का वास्तविक अभिविन्यास, उदाहरण के लिए [0,0, -1 ]>। इन कोणों और mgr.deviceMotion द्वारा एक साथ आपूर्ति की गई अंतर के बीच अंतर को कॉल करें।"अभिविन्यास अंतर" रवैया। डिवाइस के क्षणिक वास्तविक दृष्टिकोण की गणना करते समय, फिर आप डिवाइसमोशन.ट्यूड्यूड में कोणों में अभिविन्यास अंतर जोड़ सकते हैं। –

+0

हां यह सही है। – Orbitus007

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