2009-11-25 8 views
5

के साथ संदर्भ में सभी बिंदुओं को स्केल करते समय लाइन चौड़ाई को संरक्षित करें मेरे पास कुछ समन्वय प्रणाली में CGPath है जिसे मैं आकर्षित करना चाहता हूं। ऐसा करने में पुराने समन्वय प्रणाली को संदर्भ के एक पर स्केल करना शामिल है। उस उद्देश्य के लिए, मैं CGContextConcatCTM() का उपयोग करता हूं जो सभी बिंदुओं को बदलता है जैसा इसे करना चाहिए। लेकिन, चूंकि यह एक स्केलिंग ऑपरेशन है, क्षैतिज/ऊर्ध्वाधर रेखा चौड़ाई बदल जाती है। जैसे एक्स-दिशा में 10 का एक पैमाने, लेकिन वाई-दिशा में 1 की वजह से ऊर्ध्वाधर रेखाएं क्षैतिज वाले 10 गुना मोटी हो सकती हैं। अनुवाद मैट्रिक्स (उदा। CGAffineTransform) के उपयोग को आसानी से रखने का कोई तरीका है, लेकिन एक ही समय में लाइन चौड़ाई स्केल नहीं करना, उदा। CGPathApplyAffineTransformToPoints जैसे फ़ंक्शन?CGAffineTransform

चीयर्स

MrMage

उत्तर

3

आप CGPathApply का प्रयोग कर एक राह में तत्वों के माध्यम से पुनरावृति कर सकते हैं। यह केवल एक लाइनर की तुलना में थोड़ा अधिक जटिल है, लेकिन यदि आप इसे एक साधारण सहायक समारोह में पैकेज करते हैं, तो यह आपके लिए उपयोगी हो सकता है।

typedef struct { 
    CGMutablePathRef path; 
    CGAffineTransform transform; 
} PathTransformInfo; 

static void 
PathTransformer(void *info, const CGPathElement *element) 
{ 
    PathTransformInfo *transformerInfo = info; 

    switch (element->type) { 
     case kCGPathElementMoveToPoint: 
      CGPathMoveToPoint(transformerInfo->path, &transformerInfo->transform, 
           element->points[0].x, element->points[0].y); 
      break; 

     case kCGPathElementAddLineToPoint: 
      CGPathAddLineToPoint(transformerInfo->path, &transformerInfo->transform, 
           element->points[0].x, element->points[0].y); 
      break; 

     case kCGPathElementAddQuadCurveToPoint: 
      CGPathAddQuadCurveToPoint(transformerInfo->path, &transformerInfo->transform, 
             element->points[0].x, element->points[0].y, 
             element->points[1].x, element->points[1].y); 
      break; 

     case kCGPathElementAddCurveToPoint: 
      CGPathAddCurveToPoint(transformerInfo->path, &transformerInfo->transform, 
            element->points[0].x, element->points[0].y, 
            element->points[1].x, element->points[1].y, 
            element->points[2].x, element->points[2].y); 
      break; 
     case kCGPathElementCloseSubpath: 
      CGPathCloseSubpath(transformerInfo->path); 
      break; 
    } 
} 

इसका इस्तेमाल करने के लिए आप क्या करेंगे (इस भाग मैं एक सहायक समारोह के अंदर रखा है):

PathTransformInfo info; 
    info.path = CGPathCreateMutable(); 
    info.transform = CGAffineTransformMakeScale(2, 1); 

    CGPathApply(originalPath, &info, PathTransformer); 

तब्दील पथ यहाँ एक संस्करण है कि एक नया रास्ता बनाता है और यह बदल देती है इस बिंदु पर info.path में है।

+0

धन्यवाद! यह वही करेगा जो मैंने मांगा था, लेकिन दुर्भाग्य से, यह मुझे पूरे पथ को फिर से बनाने के प्रदर्शन का लाभ नहीं देगा। यदि यह एकमात्र उत्तर है, तो मैं इसे समाधान के रूप में चिह्नित करूंगा। – MrMage

6

जब आप पथ जोड़ते हैं तो परिवर्तन करें, लेकिन फिर पथ को स्ट्रोक करने से पहले ट्रांसफॉर्म को हटा दें। इस के बजाय:

CGContextSaveGState(ctx); 
CGContextScaleCTM(ctx, 10, 10); // scale path 10x 

CGContextAddPath(ctx, somePath); 

CGContextSetStrokeColorWithColor(ctx, someColor); 
CGContextSetLineWidth(ctx, someWidth); // uh-oh, line width is 10x, too 
CGContextStrokePath(ctx); 

CGContextRestoreGState(ctx);  // back to normal 

यह करें:

CGContextSaveGState(ctx); 
CGContextScaleCTM(ctx, 10, 10); // scale path 10x 

CGContextAddPath(ctx, somePath); 

CGContextRestoreGState(ctx);  // back to normal 

CGContextSetStrokeColorWithColor(ctx, someColor); 
CGContextSetLineWidth(ctx, someWidth); 
CGContextStrokePath(ctx); 
+0

मेरे पास वर्तमान में कोई मुद्दा नहीं है, लेकिन क्या आपने इसे आजमाया? यदि यह वर्णन के अनुसार काम करता है, तो यह बेहतर जवाब होगा। – MrMage

+0

@MrMage हां, मुझे एक ही समस्या होने पर आपका प्रश्न मिला, और फिर मैं थोड़ी देर बाद अपने स्वयं के समाधान के साथ आया। – bugloaf

+0

धन्यवाद, यह मेरे लिए काम किया। ऐसा लगता है कि यह आधिकारिक उत्तर होना चाहिए। –

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