2011-01-12 15 views
8

अरे, मैं यह समझने की कोशिश कर रहा हूं कि उपयोगकर्ता इनपुट के आधार पर आईओएस में बेजियर वक्र कैसे उत्पन्न करें। क्या इसके लिए कोई मौजूदा कक्षाएं हैं? क्या कोई मुझे एक सामान्य सारांश दे सकता है कि क्या आवश्यक होगा? मुझे सिर्फ दाहिने पैर पर शुरू करने में मदद की ज़रूरत है।आईओएस में मेरी उंगली के साथ बेजियर वक्र ड्राइंग?

+0

thats तुम क्या जरूरत है। बस इस ट्यूटोरियल को देखें [आईओएस के लिए एक सरल चित्रकारी ऐप कैसे बनाएं] (http://blog.effectiveui.com/?p=8105) – fyasar

+2

माइक नाचबौर के ब्लॉग पर इस पर एक पूर्ण लेखन है। [आप यहां पोस्ट पा सकते हैं] (http://nachbaur.com/blog/core-animation-part-4), और यह उपयोगकर्ता द्वारा खींचे गए बेजियर घटता पर ऑब्जेक्ट एनिमेट करने के बारे में है। –

+0

निम्नलिखित मेरे उत्तर की एक प्रति [संबंधित प्रश्न पर] है (http://stackoverflow.com/questions/7345251/bezier-path-with-dynamic-change-of-width/11091956#11091956)। मैंने कुछ फ़ंक्शंस लिखे हैं जो आपको ठीक करने में मदद करेंगे। [मेरी पोस्ट पर और पढ़ें] (http://www.wiggler.gr/2012/06/17/bezier-curves-control-points-calculation-not-only-in-ios/)। कोड [github पर मेरा रेपो] है (https://github.com/Petrakeas/outlineDEMO)। मेरी पोस्ट में आपको [एक वीडियो] भी मिलेगा (http://www.youtube.com/watch?v=iOHvIiryfaQ) कार्यों का उपयोग प्रदर्शित करता है। – Petrakeas

उत्तर

4

ठीक है, ऐसा करने का सबसे आसान तरीका शायद UIView उपclassing और ड्राइंग के लिए CoreGraphics का उपयोग करें। QuarzDemo से नमूना कोड देखें। अपने कस्टम व्यू क्लास के लिए drawInRect -method लागू करें। और touchesBegan के साथ उपयोगकर्ता के स्पर्श का पता लगाने, touchesMoved आदि

यहाँ एक बेज़ियर वक्र ड्राइंग के लिए एक उदाहरण कोड (QuarzDemo से लिया गया) है:

// Drawing with a white stroke color 
CGContextSetRGBStrokeColor(context, 1.0, 1.0, 1.0, 1.0); 
// Draw them with a 2.0 stroke width so they are a bit more visible. 
CGContextSetLineWidth(context, 2.0); 

// Draw a bezier curve with end points s,e and control points cp1,cp2 
CGPoint s = CGPointMake(30.0, 120.0); 
CGPoint e = CGPointMake(300.0, 120.0); 
CGPoint cp1 = CGPointMake(120.0, 30.0); 
CGPoint cp2 = CGPointMake(210.0, 210.0); 
CGContextMoveToPoint(context, s.x, s.y); 
CGContextAddCurveToPoint(context, cp1.x, cp1.y, cp2.x, cp2.y, e.x, e.y); 
CGContextStrokePath(context); 

आशा में मदद करता है कि आप शुरू हो रही है;)

+1

फ़िक्स 23: अत्यंत उपयोगी उत्तर के लिए धन्यवाद। अगर मैं आसानी से इंटरपोलेटेड वक्र चाहता हूं, तो क्या मुझे इसके लिए एल्गोरिदम विकसित करना होगा? मैं वक्र चाहता हूं कि वक्र को जितना संभव हो उतने कम से कम उपयोग कर उत्पन्न किया जाए। – Brendan

+0

हैलो @ फ़िक्स 23 कृपया इस http://stackoverflow.com/questions/20881721/calculate-controlpoints-while-drawing-in-ios को देखें और कृपया अपने विशेषज्ञ को सलाह दें – Ranjit

10

यदि आप उद्देश्य-सी में रहना चाहते हैं, तो आप UIBezierPath के addCurveToPoint का उपयोग कर सकते हैं: controlPoint1: controlPoint2: विधि। आप CGPaths के साथ समान नामित फ़ंक्शन का भी उपयोग कर सकते हैं। बेजियर वक्र का उपयोग करते समय, आपको वक्र को परिभाषित करने के लिए प्रत्येक बिंदु पर प्रारंभ बिंदु, समापन बिंदु, और नियंत्रण बिंदु की आवश्यकता होती है।

यह परिभाषित करने का एक तरीका है कि उपयोगकर्ता प्रारंभ और अंत बिंदुओं को परिभाषित करने के लिए उंगली खींचें, फिर नियंत्रण बिंदुओं पर स्क्रीन टैप करें। इसे संभालने के लिए यहां एक उदाहरण दृश्य है।

BezierView.h

enum { 
    BezierStateNone = 0, 
    BezierStateDefiningLine, 
    BezierStateDefiningCP1, 
    BezierStateDefiningCP2 
}; 
@interface BezierView : UIView { 
    CGPoint startPt, endPt, cPt1, cPt2; 
    UInt8 state; 
    UIBezierPath *curvePath; 
    @private 
    UITouch *currentTouch; 
} 
@property (nonatomic, retain) UIBezierPath *curvePath; 
@end 

BezierView.m

@interface BezierView 
@dynamic curvePath; 
- (UIBezierPath *)curvePath { 
    return [[curvePath retain] autorelease]; 
} 
- (void)setCurvePath:(UIBezierPath *)newPath { 
    id tmp = curvePath; 
    curvePath = [newPath retain]; 
    [tmp release]; 
    state = BezierStateNone; 
    [self setNeedsDisplay]; 
} 
- (void)_updateCurve { 
    UIBezierPath *path = [UIBezierPath bezierPath]; 
    [path moveToPoint:startPt]; 
    [path addCurveToPoint:endPt controlPoint1:cPt1 controlPoint2:cPt2]; 
} 
- (void)_calcDefaultControls { 
    if(ABS(startPt.x - endPt.x) > ABS(startPt.y - endPt.y)) { 
     cPt1 = (CGPoint){(startPt.x + endPt.x)/2, startPt.y}; 
     cPt2 = (CGPoint){cPt1.x, endPt.y}; 
    } else { 
     cPt1 = (CGPoint){startPt.x, (startPt.y + endPt.y)/2}; 
     cPt2 = (CGPoint){endPt.x, cPt1.y}; 
    } 
} 
- (void)drawRect:(CGRect)rect { 
    UIBezierPath *path = self.curvePath; 
    if(path) [path stroke]; 
} 
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    if(currentTouch) return; 
    if(state == BezierStateNone) { 
     state = BezierStateDefiningLine; 
     currentTouch = [touches anyObject]; 
     startPt = [currentTouch locationInView:self]; 
    } else if(state == BezierStateDefiningCP1) { 
     currentTouch = [touches anyObject]; 
     cPt1 = [currentTouch locationInView:self]; 
     [self _updateCurve]; 
    } else if(state == BezierStateDefiningCP2) { 
     currentTouch = [touches anyObject]; 
     cPt2 = [currentTouch locationInView:self]; 
     [self _updateCurve]; 
    } 
} 
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    if(!currentTouch) return; 
    if(state == BezierStateDefiningLine) { 
     endPt = [currentTouch locationInView:self]; 
     [self _calcDefaultControls]; 
     [self _updateCurve]; 
    } else if(state == BezierStateDefiningCP1) { 
     cPt1 = [currentTouch locationInView:self]; 
     [self _updateCurve]; 
    } else if(state == BezierStateDefiningCP2) { 
     cPt2 = [currentTouch locationInView:self]; 
     [self _updateCurve]; 
    } 
} 
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    if(!currentTouch) return; 
    if(state == BezierStateDefiningLine) { 
     state = BezierStateDefiningCP1; 
    } else if(state == BezierStateDefiningCP1) { 
     state = BezierStateDefiningCP2; 
    } else if(state == BezierStateDefiningCP2) { 
     state = BezierStateNone; 
    } 
    currentTouch = nil; 
} 
- (void)touchesCanceled:(NSSet *)touches withEvent:(UIEvent *)event { 
    if(state == BezierStateDefiningLine) { 
     self.curvePath = nil; 
     self.state = BezierStateNone; 
    } 
    self.currentTouch = nil; 
} 
+0

यह कुछ भी आकर्षित नहीं करता है :( – ColdSteel

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