2010-03-23 11 views
9

के साथ एक पंक्ति पर त्रिकोण/तीर ड्रॉइंग मैं स्थानों के साथ काम करने के लिए मार्ग-मेरे ढांचे का उपयोग कर रहा हूं। इस कोड में दो मार्करों (बिंदुओं) के बीच का पथ एक रेखा के रूप में खींचा जाएगा।CGContext

मेरे प्रश्न: "क्या कोड मैं जोड़ने चाहिए अगर मैं रेखा के मध्य (या ऊपर) में एक तीर जोड़ना चाहते हैं, इतना है कि यह दिशा बताते हैं"

धन्यवाद



- (void)drawInContext:(CGContextRef)theContext 
{ 
    renderedScale = [contents metersPerPixel]; 

    float scale = 1.0f/[contents metersPerPixel]; 

    float scaledLineWidth = lineWidth; 
    if(!scaleLineWidth) { 
     scaledLineWidth *= renderedScale; 
    } 
    //NSLog(@"line width = %f, content scale = %f", scaledLineWidth, renderedScale); 

    CGContextScaleCTM(theContext, scale, scale); 

    CGContextBeginPath(theContext); 
    CGContextAddPath(theContext, path); 

    CGContextSetLineWidth(theContext, scaledLineWidth); 
    CGContextSetStrokeColorWithColor(theContext, [lineColor CGColor]); 
    CGContextSetFillColorWithColor(theContext, [fillColor CGColor]); 

    // according to Apple's documentation, DrawPath closes the path if it's a filled style, so a call to ClosePath isn't necessary 
    CGContextDrawPath(theContext, drawingMode); 
} 

+0

मैं इसे http://www.codeguru.com/cpp/gm/gdi/article.php/c3683 द्वारा कुछ समय पहले मिला वैसे भी जवाब Greetz – Pete

+0

पीट के लिए Thansk, यह करने के लिए आप के लिए अच्छा हो सकता है फिर भी स्वीकार किए गए उत्तर को चिह्नित करें, या अपना जवाब उत्तर के रूप में पोस्ट करें और फिर उसे स्वीकार करें। –

+0

@Pete आपने सही उत्तर क्यों चिह्नित नहीं किया (मेरा मतलब है फ्रेडहेल्म)? – yas375

उत्तर

5

एक बार आपके पथ पर दो बिंदु होने के बाद वास्तविक त्रिकोण/तीर का चित्रण आसान होता है।

CGContextMoveToPoint(context , ax , ay); 
CGContextAddLineToPoint(context , bx , by); 
CGContextAddLineToPoint(context , cx , cy); 
CGContextClosePath(context); // for triangle 

अंक प्राप्त करना थोड़ा और मुश्किल है। आपने कहा कि एक वक्र या वक्र की श्रृंखला के विपरीत पथ एक रेखा थी। इससे यह आसान हो जाता है।

पथ पर दो बिंदु चुनने के लिए CGPathApply का उपयोग करें। शायद, यह अंतिम दो बिंदु है, जिनमें से एक kCGPathElementMoveToPoint हो सकता है और दूसरा kCGPathElementAddLineToPoint होगा। एमएक्स को चलो, मेरा पहला बिंदु और एनएक्स हो, दूसरा दूसरा हो, तो तीर एम से एन की ओर इंगित करेगा।

मान लीजिए कि आप लाइन के टिप पर तीर चाहते हैं, बीएक्स, ऊपर से एनएक्स के बराबर होगा, लाइन पर एनई। अन्य बिंदुओं की गणना करने के लिए एमएक्स, मेरे और एनएक्स, एनई के बीच एक बिंदु डीएक्स, डीई चुनें।

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

r = atan2(ny - my , nx - mx); 
bx = nx; 
by = ny; 
dx = bx + sin(r) * length; 
dy = by + cos(r) * length; 
r += M_PI_2; // perpendicular to path 
ax = dx + sin(r) * width; 
ay = dy + cos(r) * width; 
cx = dx - sin(r) * width; 
cy = dy - cos(r) * width; 

लंबाई आधार करने के लिए तीर की नोक से दूरी है, और चौड़ाई अकड़ के शाफ्ट से दूरी है, या आधा चौड़ाई तीर सिर का।

यदि पथ एक वक्र है, तो एमएक्स खोजने के बजाय, मेरे पिछले बिंदु या चाल के रूप में, यह अंतिम वक्र का अंतिम नियंत्रण बिंदु होगा। प्रत्येक नियंत्रण बिंदु वक्र के लिए एक रेखा टेंगेंट पर है और आसन्न बिंदु से गुज़र रहा है।

2

मुझे यह प्रश्न मिला क्योंकि मेरे पास वही था। मैं के उदाहरण drawnonward लिया और यह इतना करीब था ... लेकिन क्योंकि और पाप का एक flipping के साथ, मैं यह काम करने के लिए प्राप्त करने में सक्षम था:

r = atan2(ny - my , nx - mx); 
r += M_PI; 
bx = nx; 
by = ny; 
dx = bx + cos(r) * length; 
dy = by + sin(r) * length; 
r += M_PI_2; // perpendicular to path 
ax = dx + cos(r) * width; 
ay = dy + sin(r) * width; 
cx = dx - cos(r) * width; 
cy = dy - sin(r) * width; 

एक बार मैंने किया था कि, मेरे तीर बिल्कुल गलत तरीके से बताया गया । इसलिए मैंने कहा कि दूसरी पंक्ति (r += M_PI;)

धन्यवाद तैयार करने के लिए जाओ!

20
- (void) drawLine: (CGContextRef) context from: (CGPoint) from to: (CGPoint) to 
{ 
    double slopy, cosy, siny; 
    // Arrow size 
    double length = 10.0; 
    double width = 5.0; 

    slopy = atan2((from.y - to.y), (from.x - to.x)); 
    cosy = cos(slopy); 
    siny = sin(slopy); 

    //draw a line between the 2 endpoint 
    CGContextMoveToPoint(context, from.x - length * cosy, from.y - length * siny); 
    CGContextAddLineToPoint(context, to.x + length * cosy, to.y + length * siny); 
    //paints a line along the current path 
    CGContextStrokePath(context); 

    //here is the tough part - actually drawing the arrows 
    //a total of 6 lines drawn to make the arrow shape 
    CGContextMoveToPoint(context, from.x, from.y); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy - (width/2.0 * siny)), 
         from.y + (- length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy + (width/2.0 * siny)), 
         from.y - (width/2.0 * cosy + length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 

    /*/-------------similarly the the other end-------------/*/ 
    CGContextMoveToPoint(context, to.x, to.y); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy - (width/2.0 * siny)), 
         to.y + (length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy + width/2.0 * siny), 
         to.y - (width/2.0 * cosy - length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 
} 
संबंधित मुद्दे