在Apple文檔中,他們爲您提供瞭如何將NSBezierPath轉換爲CGPathRef的代碼。我需要從CGPathRef轉換到NSBezierPath。 UIBezierPath有一個名爲cgPath的屬性,所以如果我在iPhone上工作並不是問題,但我正在使用MacOS。將CGPathRef轉換爲NSBezierPath
這一定是一個老問題,我一定會在網上找到答案,但沒有運氣。可能是我錯過了一些東西。任何幫助讚賞。
在Apple文檔中,他們爲您提供瞭如何將NSBezierPath轉換爲CGPathRef的代碼。我需要從CGPathRef轉換到NSBezierPath。 UIBezierPath有一個名爲cgPath的屬性,所以如果我在iPhone上工作並不是問題,但我正在使用MacOS。將CGPathRef轉換爲NSBezierPath
這一定是一個老問題,我一定會在網上找到答案,但沒有運氣。可能是我錯過了一些東西。任何幫助讚賞。
老問題,但我相信這對他人仍然有幫助。 (您沒有指定的Objective-C或雨燕;這是一個Objective-C的答案)
可以使用CGPathApply()
一個CGPathRef
到NSBezierPath
轉換與轉換的CGPathRef
點NSBezierPath
點的回調。唯一棘手的部分是從CGPathRef
的二次曲線來NSBezierPath
的三次曲線,但there's an equation for that交談:
任何二次樣條可以被表示爲一個立方(其中三次項是零)。立方體的終點與二次方的終點相同。
CP0 = QP0 CP3 = QP2
對立方的兩個控制點有:
CP1 = QP0 + 2/3 * (QP1-QP0) CP2 = QP2 + 2/3 * (QP1-QP2)
...有因四捨五入推出了輕微的錯誤,但它通常並不明顯。
使用上面的公式,這裏是一個NSBezierPath
類別從CGPathRef
轉換:
NSBezierPath + BezierPathWithCGPath.h
@interface NSBezierPath (BezierPathWithCGPath)
+ (NSBezierPath *)JNS_bezierPathWithCGPath:(CGPathRef)cgPath; //prefixed as Apple may add bezierPathWithCGPath: method someday
@end
NSBezierPath + BezierPathWithCGPath.m
static void CGPathCallback(void *info, const CGPathElement *element) {
NSBezierPath *bezierPath = (__bridge NSBezierPath *)info;
CGPoint *points = element->points;
switch(element->type) {
case kCGPathElementMoveToPoint: [bezierPath moveToPoint:points[0]]; break;
case kCGPathElementAddLineToPoint: [bezierPath lineToPoint:points[0]]; break;
case kCGPathElementAddQuadCurveToPoint: {
NSPoint qp0 = bezierPath.currentPoint, qp1 = points[0], qp2 = points[1], cp1, cp2;
CGFloat m = (2.0/3.0);
cp1.x = (qp0.x + ((qp1.x - qp0.x) * m));
cp1.y = (qp0.y + ((qp1.y - qp0.y) * m));
cp2.x = (qp2.x + ((qp1.x - qp2.x) * m));
cp2.y = (qp2.y + ((qp1.y - qp2.y) * m));
[bezierPath curveToPoint:qp2 controlPoint1:cp1 controlPoint2:cp2];
break;
}
case kCGPathElementAddCurveToPoint: [bezierPath curveToPoint:points[2] controlPoint1:points[0] controlPoint2:points[1]]; break;
case kCGPathElementCloseSubpath: [bezierPath closePath]; break;
}
}
@implementation NSBezierPath (BezierPathWithCGPath)
+ (NSBezierPath *)JNS_bezierPathWithCGPath:(CGPathRef)cgPath {
NSBezierPath *bezierPath = [NSBezierPath bezierPath];
CGPathApply(cgPath, (__bridge void *)bezierPath, CGPathCallback);
return bezierPath;
}
@end
這樣的叫法:
//...get cgPath (CGPathRef) from somewhere
NSBezierPath *bezierPath = [NSBezierPath JNS_bezierPathWithCGPath:cgPath];