2009-11-25 27 views
5

Tôi có một số CGPath trong một số hệ tọa độ mà tôi muốn vẽ. Làm như vậy liên quan đến việc mở rộng hệ tọa độ cũ sang hệ thống bối cảnh. Vì mục đích đó, tôi sử dụng CGContextConcatCTM() để chuyển đổi tất cả các điểm theo ý muốn. Tuy nhiên, vì nó là một hoạt động mở rộng, chiều rộng đường ngang/dọc được thay đổi thành. Ví dụ. một thang điểm 10 theo hướng x, nhưng của 1 theo hướng y sẽ dẫn đến các đường thẳng đứng dày gấp 10 lần chiều ngang. Có cách nào để giữ dễ dàng sử dụng ma trận dịch hay không (ví dụ: CGAffineTransform) nhưng không được chia tỷ lệ chiều rộng đường cùng một lúc, ví dụ: một chức năng như CGPathApplyAffineTransformToPoints?Giữ nguyên chiều rộng của đường trong khi mở rộng tất cả các điểm trong ngữ cảnh bằng CGAffineTransform

Cheers

MrMage

Trả lời

3

Bạn có thể sử dụng CGPathApply để lặp qua các yếu tố trong một con đường. Nó phức tạp hơn một chút so với chỉ một lớp lót nhưng nếu bạn gói nó lên trong một hàm trợ giúp đơn giản, nó có thể hữu ích cho bạn. Dưới đây là một phiên bản đó tạo ra một con đường mới và biến đổi nó:

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; 
    } 
} 

Để sử dụng nó, bạn sẽ làm gì (đây là phần tôi sẽ đặt bên trong một hàm helper):

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

    CGPathApply(originalPath, &info, PathTransformer); 

Đường dẫn chuyển đổi đang ở trong info.path vào thời điểm này.

+0

Cảm ơn bạn! Điều này sẽ làm những gì tôi yêu cầu, nhưng thật không may, nó sẽ không cho tôi hiệu suất của việc không phải tạo lại toàn bộ con đường. Nếu đây vẫn là câu trả lời duy nhất, tôi sẽ đánh dấu nó là giải pháp. – MrMage

6

Thực hiện phép biến đổi khi bạn thêm đường dẫn, nhưng sau đó xóa biến đổi trước khi bạn vuốt đường dẫn. Thay vì điều này:

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 

Làm điều này:

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

Hiện tại tôi không có vấn đề gì nữa nhưng bạn đã thử dùng thử? Nếu nó hoạt động như mô tả, nó sẽ là câu trả lời tốt hơn. – MrMage

+0

@MrMage Có, tôi đã tìm thấy câu hỏi của bạn khi tôi gặp vấn đề tương tự, và sau đó tôi đã đưa ra giải pháp của riêng mình sau một thời gian ngắn. – bugloaf

+0

Cảm ơn, điều này đã làm việc cho tôi. Có vẻ như nó phải là câu trả lời chính thức. –

Các vấn đề liên quan