2017-08-30 9 views
2

Appleのドキュメントでは、NSBezierPathをCGPathRefに変換するコードを提供しています。私はCGPathRefからNSBezierPathに、逆の変換をする必要があります。 UIBezierPathにはcgPathというプロパティがあります。もし私がiPhone上で問題なく動作していたら、MacOSで作業しています。CGPathRefをNSBezierPathに変換する

これは古い質問でなければならず、私はインターネット上で答えを見つけましたが、運はありませんでした。私は何かが欠けている可能性があります。どんな助けもありがたい。

答えて

1

古い質問ですが、これはまだ他の人に役立つと確信しています。 (あなたは、Objective-Cのかスウィフトが指定されていませんでした。これは、Objective-Cの答えです。)

あなたはNSBezierPathポイントにCGPathRefポイントを変換するコールバックでCGPathRefNSBezierPathCGPathApply()を使用して変換することができます。 (立方用語はゼロである)

任意の二次スプラインが立方晶として表すことができる唯一のトリッキーな部分は、S立方曲線が、there's an equation for thatNSBezierPathへの二次曲線」CGPathRefから会話です。 3次元の終点は2次元と同じになります。

CP0 = QP0 
CP3 = QP2 

立方のための2つの制御点は次のとおりです。

CP1 = QP0 + 2/3 * (QP1-QP0) 
CP2 = QP2 + 2/3 * (QP1-QP2) 

...あり四捨五入に導入若干の誤差はあるが、それは、通常は顕著ではありません。上記の式を使用して

は、ここCGPathRefから変換するためのNSBezierPathカテゴリです:

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]; 
関連する問題