2009-11-25 3 views
5

나는 그릴 좌표 체계에서 CGPath을가집니다. 이렇게하려면 이전 좌표계를 컨텍스트의 좌표계로 확장해야합니다. 이를 위해 CGContextConcatCTM()을 사용하여 모든 점을 변형해야합니다. 그러나 크기 조정 작업이므로 가로/세로 선 너비가로 변경됩니다. 예 : x 방향으로 10 배, y 방향으로 1 배는 수직선이 수평선의 10 배의 두께가되도록합니다. 변환 행렬 (예 : CGAffineTransform)의 사용 편의성을 유지하면서 동시에 선 너비를 조정하지 않는 방법이 있습니까? 예 : CGPathApplyAffineTransformToPoints과 같은 함수?CGAffineTransform을 사용하여 컨텍스트의 모든 점을 스케일하는 동안 선 너비를 보존합니다.

건배

MrMage

답변

3

당신은 경로의 요소를 반복하는 CGPathApply를 사용할 수 있습니다. 단 하나의 라이너보다 조금 복잡하지만 단순한 도우미 기능으로 패키지하면 유용 할 것입니다.

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

    CGPathApply(originalPath, &info, PathTransformer); 

변환 된 경로 :

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

가 (이 내가 도우미 함수 안에 넣어 것입니다 부분입니다) 할 것입니다 그것을 사용하려면 여기에 새 경로를 생성하고 변환 한 버전이다 이 시점에서 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

고마워요, 저에게 도움이되었습니다. 그것이 공식 답변이어야하는 것 같습니다. –

관련 문제