2011-01-05 11 views
14

का उपयोग करके आईपैड पर ड्राइंग ऐप मैं ओपनजीएल का उपयोग कर आईपैड के लिए एक ड्रॉइंग ऐप (टेक्स्ट) बना रहा हूं। मैंने पहले से ही ऐप्पल के उदाहरण जीएलपेंट पर एक नज़र डाली है, और मेरा ऐप अब उस कोड पर आधारित है। मेरा ऐप चित्रों को चित्रित करने के लिए नहीं, बल्कि चित्र खींचने के लिए होना चाहिए।ओपनजीएल

ठीक है, मेरा ऐप काम करता है, मैं कुछ पाठ लिख सकता हूं। लेकिन लेखन वास्तव में अच्छा नहीं है, यह लिखने में मजाक नहीं करता है। ड्राइंग पथ चिकनी नहीं है, यह कोणीय रूप से है क्योंकि मैं एक बिंदु से दूसरे बिंदु पर एक रेखा खींच रहा हूं। और पथ हर जगह एक ही चौड़ाई है। मेरा विचार है: जब आप तेजी से लिख रहे हैं तो रेखा धीमी गति से लिखने से पतली है। यह एक असली कलम के साथ लिखने जैसा ही अनुभव होना चाहिए।

मैं पथ को कितना आसान बना सकता हूं? लेखन की गति के आधार पर मैं लाइन की चौड़ाई कैसे बदल सकता हूं?

यहां आप देख सकते कि मैं क्या मतलब है:

example

उत्तर

27

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

CGPoint drawBezier(CGPoint origin, CGPoint control, CGPoint destination, int segments) 
{ 
CGPoint vertices[segments/2]; 
CGPoint midPoint; 
glDisable(GL_TEXTURE_2D); 
float x, y; 

float t = 0.0; 
for(int i = 0; i < (segments/2); i++) 
{ 
    x = pow(1 - t, 2) * origin.x + 2.0 * (1 - t) * t * control.x + t * t * destination.x; 
    y = pow(1 - t, 2) * origin.y + 2.0 * (1 - t) * t * control.y + t * t * destination.y; 
    vertices[i] = CGPointMake(x, y); 
    t += 1.0/(segments); 

} 
//windowHeight is the height of you drawing canvas. 
midPoint = CGPointMake(x, windowHeight - y); 
glVertexPointer(2, GL_FLOAT, 0, vertices); 
glDrawArrays(GL_POINTS, 0, segments/2); 
return midPoint; 
} 

तीन अंक के आधार पर आकर्षित करेगा कि। नियंत्रण मध्यबिंदु है, जिसे आपको वापस करने की आवश्यकता है। नया मिडपॉइंट पिछले की तुलना में अलग होगा। इसके अलावा, अगर आप उपर्युक्त कोड से गुजरते हैं, तो यह केवल आधे लाइन को आकर्षित करेगा। अगला स्ट्रोक इसे भर देगा। यह आवश्यक है। इस कार्यप्रणाली को कॉल के लिए अपने कोड (ऊपर सी में है, यह Obj सी में है):

//Invert the Y axis to conform the iPhone top-down approach 
    invertedYBegCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i] CGPointValue].y; 
    invertedYEndCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+1] CGPointValue].y; 
    invertedYThirdCoord = self.bounds.size.height - [[currentStroke objectAtIndex:i+2] CGPointValue].y; 
    //Figure our how many dots you need 
    count = MAX(ceilf(sqrtf(([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
     * ([[currentStroke objectAtIndex:i+2] CGPointValue].x - [[currentStroke objectAtIndex:i] CGPointValue].x) 
     + ((invertedYThirdCoord - invertedYBegCoord) * (invertedYThirdCoord - invertedYBegCoord)))/pointCount), 1); 

    newMidPoint = drawBezier(CGPointMake([[currentStroke objectAtIndex:i] CGPointValue].x, invertedYBegCoord), CGPointMake([[currentStroke objectAtIndex:i+1] CGPointValue].x, invertedYEndCoord), CGPointMake([[currentStroke objectAtIndex:i+2] CGPointValue].x, invertedYThirdCoord), count); 

    int loc = [currentStroke count]-1; 
    [currentStroke insertObject:[NSValue valueWithCGPoint:newMidPoint] atIndex:loc]; 
    [currentStroke removeObjectAtIndex:loc-1]; 

कि कोड वर्तमान के रूप में औंधा आईपैड अंक के आधार पर मध्य बिंदु मिल जाएगा, और सेट 'नियंत्रण' बिंदु।

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

मैं वर्तमान स्ट्रोक नामक एक सरणी में पॉइंट डेटा स्टोर करता हूं, अगर यह स्पष्ट नहीं था।

यह सब आपको चाहिए।

संपादित करें:

अंक की दुकान के लिए, आप का उपयोग करना चाहिए touchesBegin और touchesEnd:

- (void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    self.currentStroke = [NSMutableArray array]; 
    CGPoint point = [ [touches anyObject] locationInView:self]; 
    [currentStroke addObject:[NSValue valueWithCGPoint:point]]; 
    [self draw]; 

} 

- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    CGPoint point = [ [touches anyObject] locationInView:self]; 
    [currentStroke addObject:[NSValue valueWithCGPoint:point]]; 
    [self draw]; 
} 


- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    CGPoint point = [ [touches anyObject] locationInView:self]; 
    [currentStroke addObject:[NSValue valueWithCGPoint:point]]; 
    [self draw]; 
} 

काफी एक पूरे ड्राइंग अनुप्रयोग नहीं है। यदि आप जीएल_Paint का उपयोग कर रहे हैं, तो आप पहले से ही बिंदु sprites का उपयोग कर रहे हैं, जो इस प्रणाली पर बना है।

+0

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

+0

या आप पूरा कोड जोड़ सकते हैं? मेरा मतलब है पूर्ण तरीकों। वह बहुत दयालु होगा। – burki

+0

जोड़ा गया स्पर्श बेगीन, छूता है, और छूता है। यह पोस्ट में एक संपूर्ण ओपनजीएल ड्राइंग एप्लिकेशन है। – Beaker

4
के साथ अपने प्रश्न के दूसरे भाग के संबंध

(लेखन की गति के आधार रेखा की चौड़ाई अलग-अलग करने के लिए कैसे), आप होना चाहिए अपने touchesBegan:withEvent: और touchesMoved:withEvent: विधि में UITouch की timestamp संपत्ति का लाभ उठाकर इसे प्राप्त करने में सक्षम।

आप हाल ही में UITouch ऑब्जेक्ट के टाइमस्टैम्प को संग्रहीत करके और इसे नए से तुलना करके दो बाद के स्पर्श ईवेंट के बीच समय अंतर की गणना कर सकते हैं। समय अंतर से स्वाइपिंग गति की दूरी को विभाजित करने से आपको आंदोलन की गति का कुछ माप मिलना चाहिए।

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

+0

अभी तक धन्यवाद। मैंने पहले ही ऐसा कुछ सोचा है। अच्छा होगा अगर आपको पता था कि मेरी पहली समस्या कैसे हल करें। आशा है कि आप अपवित्र के साथ पर्याप्त खुश हैं। – burki