2011-11-06 9 views
14

मैं UIBezierPath का उपयोग कर रहा हूं, लेकिन यह प्रश्न पथ के लिए नियंत्रण बिंदुओं से संबंधित है, न कि ड्राइंग। अंक के एक सेट को देखते हुए, मैं एक रास्ता प्रस्तुत कर सकता हूं। हालांकि, मैं यह समझने में सक्षम नहीं हूं कि फोटो वक्र संपादक (How to implement a Photoshop Curves editor in UIKit) जैसी चिकनी रेखा रखने के लिए नियंत्रण बिंदुओं की गणना कैसे करें।अंक के एक सेट दिए गए एक चिकनी पथ के लिए नियंत्रण बिंदुओं की गणना कैसे करें?

निकटतम जवाब मैंने देखा है यहाँ है: how can i trace the finger movement on touch for drawing smooth curves?

हालांकि, मैं अभी भी उचित गणना नहीं समझ सकता है। यह कोड में निष्कर्ष निकालने के लिए ऊपर:

for (int i = 0; i< points; i++) 
{ 
    ... 

    [path addQuadCurveToPoint:nextPoint controlPoint:WTF]; 
} 
+5

मौन इतनी जोर से दर्द होता है। – akaru

+0

क्या आप वक्र को अपने प्रत्येक दिए गए बिंदुओं से बिल्कुल गुजरना चाहते हैं? या आप चाहते हैं कि एक चिकनी वक्र बस कुछ दिए गए बिंदुओं के करीब हो सकता है? –

+0

@robmayoff मुझे लगता है कि यह काफी आसान है अगर यह बहुत आसान ऑपरेशन है। – akaru

उत्तर

12

छवि आप से जुड़ा हुआ एक उदाहरण है कि द्विघात घटता का उपयोग नहीं करता है, इसलिए मैं छवि के साथ चलाने के लिए जा रहा हूँ और नहीं कोड।

आईओएस (और ओएस एक्स) पर एक बेजियर पथ मूल रूप से ड्राइंग कमांड और पॉइंट्स की एक सूची है। उदाहरण के लिए: में

[path moveTo:CGMakePoint(1,1)]; 
[path curveToPoint:(10,10) controPoint1:(3,7) controlPoint2:(4,1)]; 
[path curveToPoint:(10,10) controPoint1:(15,17) controlPoint2:(21,11)]; 
[path closePath]; 

परिणाम: एक बेज़ियर रास्ते पर

moveto (1,1)  
curveto (10,10) (3,7) (4,1) 
curveto (20,0) (15,17) (21,11)  
closepath 

नियंत्रण अंक एक बिंदु के बाहर दिशा और वक्र की दर को नियंत्रित। पहला नियंत्रण बिंदु (सीपी) पिछले बिंदु से बाहर वक्र की दिशा और दर को नियंत्रित करता है और दूसरा सीपी उस बिंदु के लिए नियंत्रित करता है जिस पर आप घुमा रहे हैं। एक वर्गबद्ध वक्र के लिए (जो आप addQuadCurveToPoint का उपयोग करते हैं: controlPoint:), इन दोनों बिंदुओं के समान हैं, जैसा कि आप विधि here विधि के दस्तावेज़ों में देख सकते हैं।

अंकों के एक सेट के साथ एक चिकनी वक्र प्राप्त करना सीपी 1 और सीपी 2 को एक दूसरे के साथ कोलिनेर बनाना शामिल है और यह रेखा उस सेगमेंट के किसी भी छोर पर बिंदुओं के समानांतर हो।

Annotated curve

यह कुछ ऐसा दिखाई देगा:

[path moveTo:2]; 
[path curveTo:3 controlPoint1:cp1 controlPoint2:cp2]; 

cp1 और CP2 कुछ निरंतर लाइन की लंबाई को चुनने और कुछ ज्यामिति करके गणना की जा सकती (मैं अपने सभी लाइन समीकरणों भूल अभी लेकिन वे ' पुनः easily googleable)

उस सेगमेंट के कर्वेटो कॉल के लिए नियंत्रण बिंदु निर्दिष्ट करने के लिए एक सेगमेंट और # -> # (सीपी #) को नामित करने के लिए # -> # का उपयोग करने के लिए जा रहा है।

अगला मुद्दा वक्र को 2-> 3 सेगमेंट में 3-> 4 सेगमेंट में आसान बना रहा है। इस बिंदु पर आपके कोड में, आपके पास 2-> 3 (सीपी 2) के लिए गणना की गई एक नियंत्रण बिंदु होनी चाहिए। पहले से आपकी निरंतर रेखा की लंबाई को देखते हुए (यह आपके द्वारा प्राप्त वक्र के कितने तेज़ को नियंत्रित करेगा), आप 3-> 4 के लिए एक बिंदु कोलिनेर प्राप्त करके 2-> 3 (सीपी 2) और आरेख में बिंदु 3 प्राप्त करके सीपी 1 की गणना कर सकते हैं। फिर 3-> 4 (सीपी 2) की गणना करें जो 3-> 4 (सीपी 1) के साथ कोलिनेर है और 3 और बिंदु 4 रूप को इंगित करने वाली रेखा के समानांतर है। कुल्ला और अपने अंक सरणी के माध्यम से दोहराना।

+1

प्रतिक्रिया के लिए धन्यवाद। दुर्भाग्यवश, लिंक के माध्यम से पढ़ने के बाद भी मैं सही विधि निर्धारित करने में असमर्थ हूं। मैं अपने दिमाग को दोषी ठहराता हूं। – akaru

+0

नियंत्रण बिंदुओं की गणना के लिए कोड लिखने का कोई तरीका नहीं है। –

4

मुझे यकीन नहीं है कि इससे कितना मदद मिलेगी, लेकिन मुझे इस ऐप में अनुसरण करने के लिए नोट्स के लिए घुमावदार पथ को लागू करने के समान कुछ करना था, (www.app.net/hereboy)। अनिवार्य रूप से, यह तीन घटता के साथ एक रास्ता है।

ऐसा करने के लिए मैंने प्रति अंक 4 अंक, एक शुरुआती बिंदु, एक अंतिम बिंदु, और दो नियंत्रण बिंदु 25% अंक और 75% अंक पर बनाया।

//create points along the keypath for curve. 
CGMutablePathRef curvedPath = CGPathCreateMutable(); 
const int TOTAL_POINTS = 3; 
int horizontalWiggle = 15; 

int stepChangeX = (endPoint.x - viewOrigin.x)/TOTAL_POINTS; 
int stepChangeY = (endPoint.y - viewOrigin.y)/TOTAL_POINTS; 

for(int i = 0; i < TOTAL_POINTS; i++) { 
    int startX = (int)(viewOrigin.x + i * stepChangeX); 
    int startY = (int)(viewOrigin.y + i * stepChangeY); 

    int endX = (int)(viewOrigin.x + (i+1) * stepChangeX); 
    int endY = (int)(viewOrigin.y + (i+1) * stepChangeY); 

    int cpX1 = (int)(viewOrigin.x + (i+0.25) * stepChangeX); 
    if((i+1)%2) { 
     cpX1 -= horizontalWiggle; 
    } else { 
     cpX1 += horizontalWiggle; 
    } 
    int cpY1 = (int)(viewOrigin.y + (i+0.25) * stepChangeY); 

    int cpX2 = (int)(viewOrigin.x + (i+0.75) * stepChangeX); 
    if((i+1)%2) { 
     cpX2 -= horizontalWiggle; 
    } else { 
     cpX2 += horizontalWiggle; 
    } 
    int cpY2 = (int)(viewOrigin.y + (i+0.75) * stepChangeY); 

    CGPathMoveToPoint(curvedPath, NULL, startX, startY); 
    CGPathAddCurveToPoint(curvedPath, NULL, cpX1, cpY1, cpX2, cpY2, endX, endY); 
} 

गुड लक:

यहाँ कोड है कि मैं यह करने के लिए लिखा है!

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

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