2012-04-11 27 views
14

कोको/टच में पर मूल्य की गणना करने CAMediaTimingFunction का उपयोग करना, CAMediaTimingFunction चार नियंत्रण अंक है कि एक समय समारोह की एक घन बेज़ियर वक्र निर्दिष्ट प्रतिनिधित्व करता है। (-> 1 0) एक आवेदन के लिए मैं मैं परिणाम निकालने में सक्षम होना चाहते हैं एक मनमाना समय t पर बेज़ियर वक्र कहा की लिख रहा हूँ। , एक अदिश मूल्य में एप्पल के कार्यान्वयन परिणाम (आप कर सकते हैंसमय (टी)

B(t) = (1 - t)^3 * P0 + 3 * (1 - t)^2 * t * P1 + 3 * (1 - t) * t^2 * P2 + t^2 * P3

हालांकि: क्या मुझे भ्रमित कर रहा है कि जब मैं ऊपर देखो कैसे do this करने के लिए, परिणाम एक बिंदु के रूप में अच्छी तरह से, माना जाता है कि नहीं एक अदिश है इस ग्राफ पर देखें कि वे एक्स (टी) बनाम टी: http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Animation_Types_Timing/Articles/Timing.html#//apple_ref/doc/uid/TP40006670-SW1)

तो ऐप्पल केवल परिणाम के वाई समन्वय को अनदेखा करता है और केवल एक्स के साथ सौदा करता है? यह अजीब है क्योंकि तब आप y के बिल्कुल परिणाम को प्रभावित नहीं करेगा के रूप में नियंत्रण बिंदुओं में पारित बल्कि को नियंत्रित scalars की जरूरत नहीं होगी लगता है।

+0

मुझे लगता है कि यदि आप प्रश्न के संदर्भ में विस्तार कर सकते हैं तो मैं शायद आपके प्रश्न का बेहतर उत्तर दे सकता हूं। क्या आप कुछ एनिमेट करने के लिए CAMediaTimingFunction का उपयोग कर रहे हैं? यदि हां, तो क्या यह एक कीफ्रेम एनीमेशन है? – jin

उत्तर

4

नोट: मैं CoreAnimation पर एक विशेषज्ञ नहीं हूं। आपके द्वारा लिंक किए गए दस्तावेज़ों को पढ़ने से यह मेरी समझ है।

एप्पल यहाँ प्रणाली समन्वय है, जो कुछ भ्रम की स्थिति पैदा कर रही है मिश्रण है।

उदाहरण भूखंडों में x(t) कुछ मार्ग के किनारे एक अदिश प्रगति का प्रतिनिधित्व करता है, एक भौतिक नहीं समन्वय।

नियंत्रण CAMediaTimingFunction में प्रयोग किया जाता अंक इस प्रगति, नहीं एक ज्यामितीय अंक वर्णन किया जाता है। भ्रम को जोड़ने के लिए, नियंत्रण बिंदुओं में x वास्तव में x(t) भूखंडों पर करने के लिए भूखंडों पर t और नियंत्रण बिंदुओं में y को मैप करता है।

उदाहरण के रूप में kCAMediaTimingFunctionEaseInEaseOut के लिए साजिश लेने के लिए, इस प्लॉट को लगभग नियंत्रण बिंदु (0,0), (0.5,0), (0.5,1), (1,1) द्वारा वर्णित किया जाएगा।

+0

आप वास्तव में सही हैं कि समस्या यह थी कि टी का मतलब है एक्स और एक्स (टी) का मतलब है y। प्रश्न यह है कि y को कुछ एक्स को कैसे ढूंढें, हालांकि अभी यह क्यूबिक समीकरण को हल करना शामिल है जो एक कठिन कठिन कार्य है)। –

+2

@ फ्रांसिस्को आपने इसे उत्तर के रूप में चिह्नित किया है, लेकिन जैसा कि आप टिप्पणी में बताते हैं, वास्तविक प्रश्न अभी भी किसी दिए गए x के लिए y प्राप्त करना है। क्या आपने कभी इसे हल किया है? चीयर्स। – epologee

+1

@jin: असल में, मैंने केवल CAMediaTimingFunction विधि getControlPointAtIndex का उपयोग kCAMediaTimingFunctionEaseInEaseOut टाइमिंग फ़ंक्शन के नियंत्रण बिंदुओं से पूछताछ करने के लिए किया है, और नियंत्रण बिंदु (.42, 0) और (.58, 1) हैं। (पहला और अंतिम अंक हमेशा 0,0 और 1,1) –

1

बेस्ट संकेत शायद वेबकिट के स्रोत कोड में UnitBezier.h होगा। वास्तव में, मुझे लगता है कि ऐप्पल कोर एनीमेशन के अंदर एक ही कोड का उपयोग करता है।

अधिक लंबा, वे गणना पैरामीटर t (जिसका समय के साथ कुछ भी नहीं है) का उपयोग x के मान के साथ किया गया है जिसमें वास्तव में समय मान होता है। तब वे Newton-Raphson method (additional explanation with examples) का उपयोग करें। चूंकि यह असफल हो सकता है, वे बायसेक्शन ("विभाजन और जीत") का उपयोग करने के लिए थोड़ा और फिर से शुरू करते हैं। इसे solveCurveX() विधि में देखें।

पैरामीटर t प्राप्त करने के बाद (जो आवश्यक है कि क्यूबिक बेजियर को पैरामीट्रिक रूप से परिभाषित किया गया है), वे बस y की गणना करने के लिए इसका उपयोग करते हैं। इसे solve() विधि में देखें।

वैसे, Cappuccino के एक बड़े प्रशंसक, और अभी भी :-)

8

CoreAnimation के CAMediaTimingFunction एटलस की रिहाई के लिए उम्मीद कर आप क्या चाहते हैं करता है लेकिन के लिए हो रही है 'y' का खुलासा नहीं करता किसी दिए गए 'एक्स' बहुमुखी (एनीमेशन) के उपयोग के लिए, बल्कि हुड के नीचे एनीमेशन सिस्टम के लिए हल किए गए हल मूल्यों को केवल फ़ीड करता है।

मुझे इसे स्वयं की आवश्यकता है ताकि built a class with the interface and capabilities exactly like CAMediaTimingFunction but with the needed -valueForX: method; उपयोग का उदाहरण:

RSTimingFunction *heavyEaseInTimingFunction = [RSTimingFunction timingFunctionWithControlPoint1:CGPointMake(0.8, 0.0) controlPoint2:CGPointMake(1.0, 1.0)]; 
CGFloat visualProgress = [heavyEaseInTimingFunction valueForX:progress]; 

आप आसानी में, आसानी से बाहर बना सकते हैं ease-in-आराम-आउट या वास्तव में किसी भी घटता a cubic Bézier curve साथ वर्णित किया जा सकता है। कार्यान्वयन गणित वेबकोर (वेबकिट) पर आधारित है, जो अनुमानतः संभवतः कोरएनीमेशन हुड के तहत भी उपयोग कर रहा है।

का आनंद लें, राफेल

+0

+1 अच्छा काम :) - क्या आपको कोई विचार है कि कैसे भौतिकी आधारित आईओएस 7 एनिमेशन हुड के नीचे काम करते हैं? ('एनिमेट ... का उपयोग करकेप्रिंगविथडैम्पिंग: ..') – Robert

+1

वे एक भौतिकी इंजन का उपयोग करते हैं - स्प्राइटकिट के साथ साझा किया जाता है -, जो कि इन विशेष गणनाओं के लिए लोकप्रिय आरके 4 इंटीग्रेटर का उपयोग करता है। आरके 4 इंटीग्रेटर को वास्तव में अच्छी तरह से समझाया गया है http://gafferongames.com/game-physics/integration-basics/ सी ++ में एक महान कोड नमूना के साथ। –

+0

बहुत बुरा यह आईओएस 7 में अब और काम नहीं करता है।:/ – Andy

1

यह दुर्भाग्यपूर्ण है, लेकिन कोर एनिमेशन अपने एनीमेशन समय के लिए अपने आंतरिक कम्प्यूटेशनल मॉडल का खुलासा नहीं करता। हालांकि, मेरे लिए वास्तव में अच्छा काम किया है काम करने के लिए कोर एनीमेशन का उपयोग करना है!

  1. एक CALayer एक मूल्यांकनकर्ता
  2. 0.0
  3. को true
  4. सेट speed को ((0.0, 0.0), (1.0, 1.0))
  5. सेट isHidden करने के लिए अपने अवधि सेट के रूप में काम करने के लिए कुछ कंटेनर परत
  6. को यह परत जोड़ें बनाएं जब आप किसी भी CAMediaTimingFunction का मूल्यांकन करना चाहते हैं, तो एक संदर्भ बनाएं एनीमेशन:

    let basicAnimation = CABasicAnimation(keyPath: "bounds.origin.x") 
    basicAnimation.duration = 1.0 
    basicAnimation.timingFunction = timingFunction 
    basicAnimation.fromValue = 0.0 
    basicAnimation.toValue = containerLayer.bounds.width 
    
    referenceLayer.add(basicAnimation, forKey: "evaluatorAnimation") 
    
  7. सेट संदर्भ परत की timeOffset जो कुछ सामान्यीकृत इनपुट मूल्य के लिए (यानी, 0.0 और 1.0 के बीच) आप मूल्यांकन करना चाहते:

    referenceLayer.timeOffset = 0.3 // 30% into the animation 
    
  8. संदर्भ परत की प्रस्तुति परत के लिए पूछें , और इसकी वर्तमान सीमाएं मूल x मान प्राप्त करें:

    if let presentationLayer = referenceLayer.presentation() as CALayer? { 
        let evaluatedValue = presentationLayer.bounds.origin.x/containerLayer.bounds.width 
    } 
    

असल में, आप एक अदृश्य परत के लिए एनीमेशन चलाने के लिए कोर एनीमेशन का उपयोग कर रहे हैं। लेकिन परत का speed0.0 है, इसलिए यह एनीमेशन की प्रगति नहीं करेगा। timeOffset का उपयोग करके, हम एनीमेशन की वर्तमान स्थिति मैन्युअल रूप से समायोजित कर सकते हैं और फिर इसकी प्रस्तुति परत की एक्स स्थिति प्राप्त कर सकते हैं। यह एनीमेशन द्वारा संचालित संपत्ति के वर्तमान अनुमानित मूल्य का प्रतिनिधित्व करता है।

यह थोड़ा अपरंपरागत है, लेकिन इसके बारे में हैकी कुछ भी नहीं है। यह CAMediaTimingFunction के आउटपुट वैल्यू का वफादार है जैसा कि आप प्राप्त कर सकते हैं क्योंकि कोर एनीमेशन वास्तव में इसका उपयोग कर रहा है।

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