2011-11-26 18 views
35

मैं कोर ग्राफिक्स एफ़िन को एक बिंदु x, y कोण कोण के चारों ओर घूर्णन के लिए कैसे बदल सकता हूं, केवल CGAffineTransformMake() प्लस math.h ट्रिग फ़ंक्शंस जैसे पाप(), cos() इत्यादि का उपयोग करके एक ही कॉल का उपयोग कर सकता हूं। , और कोई अन्य सीजी कॉल नहीं।एक बिंदु एफ़िन एक बिंदु के चारों ओर घूर्णन के लिए बदल जाता है?

अन्य उत्तर यहां कई कोर ग्राफिक्स कॉल का उपयोग करके कई स्टैक्ड ट्रांसफॉर्म या बहु-चरण परिवर्तनों को स्थानांतरित करने, घुमाने और स्थानांतरित करने के बारे में प्रतीत होते हैं। वे उत्तर मेरी विशिष्ट आवश्यकताओं को पूरा नहीं करते हैं।

+2

क्यों आप 'CGAffineTransformMake()' के लिए एक कॉल की ज़रूरत है? स्टैक्ड कॉल सटीक एक ही परिणाम उत्पन्न करते हैं, सिवाय इसके कि वे ऐसे तरीके से ऐसा करते हैं जो पठनीय है और समझ में आता है।यदि आप वास्तव में इसे एक ही कॉल में करना चाहते हैं, तो आप पूरी तरह से लाभ के लिए, स्टैक्ड कॉल में उपयोग किए गए समान गणित को दोहराने के लिए तैयार नहीं होंगे। –

+3

यह क्या आवश्यकताएं हो सकती हैं? आप CGAffineTransformConcat का उपयोग करके उन "स्टैक्ड" रूपांतरणों को एक CGAffineTransform में जोड़ सकते हैं। नतीजा व्यक्तिगत घटकों के सूत्रों के समान होगा, और इसमें शामिल गणनाएं आंतरिक रूप से समान होंगी, या संभवतः CGAffineTransformConcat के मामले में अधिक अनुकूल होंगी। – morningstar

+0

मैं मैट्रिक्स समीकरणों को मिलान करने के लिए एक गैर-ग्राफिक्स मॉडल ऑब्जेक्ट पर एक अलग (आवश्यक रूप से यूक्लिडियन) ज्यामितीय 2 डी स्पेस में उपयोग करना चाहता हूं। – hotpaw2

उत्तर

101

बिंदु के आसपास कोण एक का एक रोटेशन (एक्स, वाई) affine परिवर्तन से मेल खाती है:

CGAffineTransform transform = CGAffineTransformMake(cos(a),sin(a),-sin(a),cos(a),x-x*cos(a)+y*sin(a),y-x*sin(a)-y*cos(a)); 

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

इसके अलावा, आप का उपयोग कर कोड के तीन लाइनों में ठीक इसी कार्य को पूरा कर सकते हैं:

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y); 
transform = CGAffineTransformRotate(transform, a); 
transform = CGAffineTransformTranslate(transform,-x,-y); 

किसी दृश्य को यह आवेदन कर रहे थे, तो आप भी बस एक रोटेशन CGAffineTransformMakeRotation के माध्यम से बदलने इस्तेमाल कर सकते हैं (क), बशर्ते आप उस बिंदु को प्रतिबिंबित करने के लिए दृश्य की परत की एंकरपॉइंट प्रॉपर्टी सेट करें जिसे आप घूमना चाहते हैं। हालांकि, ऐसा लगता है कि आप इसे देखने के लिए आवेदन करने में रूचि नहीं रखते हैं।

अंत में, यदि आप इसे गैर-यूक्लिडियन 2 डी स्पेस में लागू कर रहे हैं, तो आप एक एफ़िन रूपांतरण नहीं चाहते हैं। एफ़िन ट्रांसफॉर्मेशन यूक्लिडियन स्पेस की आइसोमेट्री हैं, जिसका अर्थ है कि वे मानक यूक्लिडियन दूरी, साथ ही साथ कोणों को भी संरक्षित करते हैं। यदि आपकी जगह यूक्लिडियन नहीं है, तो आपके द्वारा इच्छित परिवर्तन वास्तव में परिष्कृत नहीं हो सकता है, या यदि यह गठबंधन है, तो घूर्णन के लिए मैट्रिक्स उतना आसान नहीं हो सकता जितना मैंने पाप और कोस के साथ लिखा था। उदाहरण के लिए, यदि आप हाइपरबॉलिक स्पेस में थे, तो आपको हाइपरबॉलिक ट्रिग फ़ंक्शंस सिन्हा और कोश, फॉर्मूला में अलग-अलग + और - संकेतों के साथ उपयोग करने की आवश्यकता हो सकती है।

पीएस मैं यह भी पढ़ना चाहता था कि किसी को भी "एफ़िन" को "पूछने" के रूप में संक्षिप्त "ए" के साथ उच्चारण किया जाए, न कि "सक्षम" के रूप में लंबे समय तक "ए"। मैंने ऐप्पल कर्मचारियों को अपने डब्ल्यूडब्ल्यूडीसी वार्ता में गलत तरीके से सुना है।

+1

बिल्कुल 'ए' क्या है? – jjxtra

+1

'ए' रेडियंस में कोण है – Curtis

+2

यदि आप उच्चारण पर सुझाव देने जा रहे हैं, तो आपको यह भी निर्दिष्ट करना चाहिए कि यह "ठीक" या -फिन में "फीन" जैसा है। लेकिन शायद मैं उस हिस्से को गलत पाने के लिए अकेला हूं। : -/ –

1

इस लिंक को देखें: Rotating an iPhone View Around a Point। यह आपकी मदद कर सकता है। लेख के निचले भाग में, "एंकर पॉइंट बदलें" शीर्षक वाला एक अनुभाग है। यह शायद आपकी आवश्यकताओं के लिए सबसे उपयुक्त है, हालांकि दृश्य को ऑफ़सेट न करने के लिए कुछ मुआवजे किए जाने चाहिए।

2

मेरे जैसे लोगों के लिए, जो एक छवि को घुमाने और इसे ठीक से स्केल करने के लिए एक पूर्ण समाधान की तलाश में संघर्ष कर रहे हैं, जिसमें कुछ घंटे बाद यह सबसे पूर्ण और निर्दोष समाधान है। प्राप्त किया है

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

मैंने पूरे समाधान को एक सीआईफ़िल्टर सबक्लास में पैक किया है जिसे आप gist here कर सकते हैं।

कोड के प्रासंगिक भाग के बाद:

CGFloat a = _inputDegree.floatValue; 
CGFloat x = _inputImage.extent.size.width/2.0; 
CGFloat y = _inputImage.extent.size.height/2.0; 

CGFloat scale = [self calculateScaleForAngle:GLKMathRadiansToDegrees(a)]; 

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y); 
transform = CGAffineTransformRotate(transform, a); 
transform = CGAffineTransformTranslate(transform,-x,-y); 


CGAffineTransform transform2 = CGAffineTransformMakeTranslation(x, y); 
transform2 = CGAffineTransformScale(transform2, scale, scale); 
transform2 = CGAffineTransformTranslate(transform2,-x,-y); 

CGAffineTransform concate = CGAffineTransformConcat(transform2, transform); 
संबंधित मुद्दे