2012-05-17 8 views
5

में प्रारंभ और अंत कोण के साथ अंडाकार निकालें मैं एक आईपैड ऐप लिख रहा हूं जिसमें मैं एक्सएमएल ऑब्जेक्ट्स प्रस्तुत कर रहा हूं जो स्क्रीन पर ग्राफिक्स में आकार का प्रतिनिधित्व करते हैं। उन वस्तुओं में से एक जो मैं प्रस्तुत करने की कोशिश कर रहा हूं वह arcs है। अनिवार्य रूप से ये arcs मुझे एक बाध्य आयत के साथ ही एक प्रारंभ और अंत कोण प्रदान करते हैं।ऑब्जेक्टिव-सी

को देखते हुए गुण:

  • एक्स
  • y
  • चौड़ाई
  • ऊंचाई
  • startAngle
  • endAngle
इन मूल्यों मैं चाप आकर्षित करने की आवश्यकता के साथ

(जो अनिवार्य रूप से एक अंडाकार का हिस्सा है)। मैं निम्नलिखित का उपयोग नहीं कर सकता:

UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)]; 
    [UIColor blackColor] setStroke]; 
    [arc stroke]; 

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

उत्तर

9

आप शायद प्राप्त कर सकते हैं कि आप क्या दीर्घवृत्त की ड्राइंग के चारों ओर एक क्लिप पथ की स्थापना करके चाहते हैं।

CGContextSaveGState(theCGContext); 
CGPoint center = CGPointMake(x + width/2.0, y + height/2.0); 
UIBezierPath* clip = [UIBezierPath bezierPathWithArcCenter:center 
                radius:max(width, height) 
               startAngle:startAngle 
                endAngle:endAngle 
               clockwise:YES]; 
[clip addLineToPoint:center]; 
[clip closePath]; 
[clip addClip]; 

UIBezierPath *arc = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(x, y, width, height)]; 
[[UIColor blackColor] setStroke]; 
[arc stroke]; 

CGContextRestoreGState(theCGContext); 

क्लिपिंग के लिए सटीक त्रिज्या महत्वपूर्ण नहीं है। इसे काफी बड़ा होने की जरूरत है ताकि यह केवल वांछित चाप के माध्यम से, अंडाकारों को सिरों पर क्लिप कर सके।

+0

धन्यवाद, एक आकर्षण की तरह काम किया (अभी भी उद्देश्य-सी के साथ-साथ ग्राफिक्स ड्राइंग के लिए नया)। –

2

आप bezierPathWithOvalInRect.

विधि परिभाषा के बजाय addQuadCurveToPoint:controlPoint: का उपयोग करना होगा प्रकार है: -

- (void)addQuadCurveToPoint:(CGPoint)endPoint controlPoint:(CGPoint)controlPoint 

CGPoint है कि तर्क (इनपुट) दोनों मापदंडों के लिए कर रहे हैं।

addQuadCurveToPoint पर कॉल करने से पहले आपको moveToPoint: का उपयोग करके प्रारंभ बिंदु भी सेट करना होगा जो वर्तमान बिंदु के रूप में कार्य करेगा (जैसा कि आप विधि में पैरामीटर के रूप में उनके प्रारंभ बिंदु को नहीं देख सकते हैं)।

अपने मामले में आप होगा

1> एक्स, अपने प्रारंभिक बिंदु के रूप y

2> x + चौड़ाई और y + समाप्ति बिंदु ऊंचाई

आप यहाँ कोण की जरूरत नहीं है या आप कोणों का उपयोग करने के लिए अपने तर्क को कार्यान्वित कर सकते हैं। चीज़ को स्पष्ट करने के लिए एक छवि अपलोड कर सकते हैं।

Here is the image describing the start point,end point and control point

+0

एक वर्गिक बेजियर वक्र नहीं करेगा। हो सकता है कि आप एक क्यूबिक बेजियर वक्र के लिए नियंत्रण बिंदुओं की गणना कर सकें, जैसे कि दिए गए गुणों के साथ एक अंडाकार खींचा जाता है।गणित के बिना किसी दिए गए जानकारी को बेजियर वक्र में अनुवाद करने की आवश्यकता होती है, यह सवाल का जवाब नहीं देती है। – thundersteele

+0

असल में, मुझे लगता है कि यदि आप पथ को स्पष्ट रूप से आकर्षित करना चाहते हैं (यानी क्लिपिंग के साथ नहीं) तो आपको elipse के लिए पैरामीट्रिक समीकरण की आवश्यकता है। फिर आपको लघु खंडों का एक गुच्छा बनाना होगा (वर्ग या घन, या यहां तक ​​कि रैखिक) जो ग्रहण को अपनाना चाहते हैं। क्लिपिंग बेहतर है। http://www.techotopia.com/index.php/An_iPhone_Graphics_Drawing_Tutorial_using_Quartz_2D#Drawing_an_Ellipse_or_Circle – samson

+1

यह एक बढ़िया Techotopia है //www.techotopia.com/index.php/ An_iOS_8_Swift_Graphics_Tutorial_using_Core_Graphics_and_Core_Image – Aardvark

3

यह श्रेणी सहायता करेगी।

#import <Foundation/Foundation.h> 

@interface UIBezierPath (OvalSegment) 

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle; 
+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle angleStep:(CGFloat)angleStep; 

@end 

#import "UIBezierPath+OvalSegment.h" 

@implementation UIBezierPath (OvalSegment) 

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle angleStep:(CGFloat)angleStep { 
    CGPoint center = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect)); 
    CGFloat xRadius = CGRectGetWidth(rect)/2.0f; 
    CGFloat yRadius = CGRectGetHeight(rect)/2.0f; 

    UIBezierPath *ellipseSegment = [UIBezierPath new]; 

    CGPoint firstEllipsePoint = [self ellipsePointForAngle:startAngle withCenter:center xRadius:xRadius yRadius:yRadius]; 
    [ellipseSegment moveToPoint:firstEllipsePoint]; 

    for (CGFloat angle = startAngle + angleStep; angle < endAngle; angle += angleStep) { 
     CGPoint ellipsePoint = [self ellipsePointForAngle:angle withCenter:center xRadius:xRadius yRadius:yRadius]; 
     [ellipseSegment addLineToPoint:ellipsePoint]; 
    } 

    CGPoint lastEllipsePoint = [self ellipsePointForAngle:endAngle withCenter:center xRadius:xRadius yRadius:yRadius]; 
    [ellipseSegment addLineToPoint:lastEllipsePoint]; 

    return ellipseSegment; 
} 

+ (UIBezierPath *)bezierPathWithOvalInRect:(CGRect)rect startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle { 
    return [UIBezierPath bezierPathWithOvalInRect:rect startAngle:startAngle endAngle:endAngle angleStep:M_PI/20.0f]; 
} 

+ (CGPoint)ellipsePointForAngle:(CGFloat)angle withCenter:(CGPoint)center xRadius:(CGFloat)xRadius yRadius:(CGFloat)yRadius { 
    CGFloat x = center.x + xRadius * cosf(angle); 
    CGFloat y = center.y - yRadius * sinf(angle); 
    return CGPointMake(x, y); 
} 

@end 
+0

ग्रेट श्रेणी !!! बस इसे सही बनाने के लिए, लाइन जोड़ने के लिए पहला बिंदु उस प्रारंभ बिंदु को शामिल नहीं करना चाहिए जो ऊपर दिए गए कोड में पहले EllipsePoint है। तो 'के लिए' कथन होना चाहिए (CGFloat कोण = startAngle + कोण चरण; कोण

+0

@RungeZhai: सच है, किया गया है! – kanobius

+0

ellipsePointForAngle गलत प्रतीत होता है, या एक विसंगति है जो मैं उपयोग की जाने वाली विधि के लिए अलग है। चूंकि कोण अंडाकार के चारों ओर बढ़ता है, यह थोड़ा और आगे ऑफसेट लग रहा है। यह आंशिक रूप से अंडाकार की चौड़ाई और ऊंचाई सहित नहीं होता है, जो कोण से एक सर्कल पर एक बिंदु खोजने से महत्वपूर्ण और अलग है। – VagueExplanation