2016-05-07 26 views
2

文字の輪郭に沿って移動するSKSpriteNodesを作成したいと思います。私は赤い線をたどるためにスプライトを希望スイフト:閉じたCGPathにポイントを追加するには?

enter image description here

:私は多くの手紙を持っていますが、ここでは一例です。私は主に私の問題をカバーしていることを、この答えを見つけました:私のスプライトが周りの完全なパスを完了していないとして、私はまだ問題に遭遇しかし

let font = UIFont(name: "HelveticaNeue", size: 64)! 


var unichars = [UniChar]("P".utf16) 
var glyphs = [CGGlyph](count: unichars.count, repeatedValue: 0) 
let gotGlyphs = CTFontGetGlyphsForCharacters(font, &unichars, &glyphs, unichars.count) 
if gotGlyphs { 
    let cgpath = CTFontCreatePathForGlyph(font, glyphs[0], nil)! 
    let path = UIBezierPath(CGPath: cgpath) 
    print(path) 
    XCPlaygroundPage.currentPage.captureValue(path, withIdentifier: "glyph \(glyphs[0])") 
} 

Get path to trace out a character in an iOS UIFont

答えは、この良いとワーキングサンプルコードが付属していますすべての手紙のための手紙が代わりに「P」は、ここで停止します(と下から開始)で:

enter image description here

私はそうのようpathにいくつかのポイントを追加してみました:

CGPathAddLineToPoint(path, nil, 0, 0) 

が、結果はので、おそらく動作しません。追加ポイントは<Close>ステートメントの後です。

<UIBezierPath: 0x7889ff70; <MoveTo {25.950001, 55.800003}>, 
<LineTo {25.950001, 95.100006}>, 
<LineTo {53.850002, 95.100006}>, 
<QuadCurveTo {71.625, 90.075005} - {66, 95.100006}>, 
<QuadCurveTo {77.25, 75.450005} - {77.25, 85.050003}>, 
<QuadCurveTo {71.625, 60.750004} - {77.25, 65.850006}>, 
<QuadCurveTo {53.850002, 55.800003} - {66, 55.650002}>, 
<Close>, 
<MoveTo {11.700001, 107.10001}>, 
<LineTo {11.700001, 0}>, 
<LineTo {25.950001, 0}>, 
<LineTo {25.950001, 43.800003}>, 
<LineTo {58.650002, 43.800003}>, 
<QuadCurveTo {83.175003, 52.050003} - {74.850006, 43.650002}>, 
<QuadCurveTo {91.5, 75.450005} - {91.5, 60.450001}>, 
<QuadCurveTo {83.175003, 98.775002} - {91.5, 90.450005}>, 
<QuadCurveTo {58.650002, 107.10001} - {74.850006, 107.10001}>, 
<Close>, 
<LineTo {0, 0}> 

答えて

2

まず、からすべての要素を取得する方法が必要です。

私はSwiftmethodに翻訳しました(使用方法の例もあります)。

あなたのコードでわかるように、あなたのパスを構成する要素の種類を知る必要がありますが、と一緒に働いています(それは複雑ではありません)。このような二つの出力アレイ:その後

//MARK: - CGPath extensions 
extension CGPath { 
    func getPathElementsPointsAndTypes() -> ([CGPoint],[CGPathElementType]) { 
      var arrayPoints : [CGPoint]! = [CGPoint]() 
      var arrayTypes : [CGPathElementType]! = [CGPathElementType]() 
      self.forEach { element in 
       switch (element.type) { 
       case CGPathElementType.MoveToPoint: 
        arrayPoints.append(element.points[0]) 
        arrayTypes.append(element.type) 
       case .AddLineToPoint: 
        arrayPoints.append(element.points[0]) 
        arrayTypes.append(element.type) 
       case .AddQuadCurveToPoint: 
        arrayPoints.append(element.points[0]) 
        arrayPoints.append(element.points[1]) 
        arrayTypes.append(element.type) 
        arrayTypes.append(element.type) 
       case .AddCurveToPoint: 
        arrayPoints.append(element.points[0]) 
        arrayPoints.append(element.points[1]) 
        arrayPoints.append(element.points[2]) 
        arrayTypes.append(element.type) 
        arrayTypes.append(element.type) 
        arrayTypes.append(element.type) 
       default: break 
       } 
      } 
      return (arrayPoints,arrayTypes) 
    } 
} 

あなたは点の配列と私たちのリストの各点が何であるかの種類を説明したタイプの鏡面配列を持っています。今回はすべてclosePathが削除されます。

func createNewPath(path:CGPath) -> UIBezierPath { 
     let (points,types) = path.getPathElementsPointsAndTypes() 
     if points.count <= 1 { 
      return UIBezierPath() // exit 
     } 

     let pathRef = UIBezierPath() 
     var i = 0 
     while i < points.count { 
      switch (types[i]) { 
       case CGPathElementType.MoveToPoint: 
        pathRef.moveToPoint(CGPointMake(points[i].x,points[i].y)) 
       case .AddLineToPoint: 
        pathRef.addLineToPoint(CGPointMake(points[i].x,points[i].y)) 
       case .AddQuadCurveToPoint: 
        pathRef.addQuadCurveToPoint(CGPointMake(points[i].x,points[i].y), controlPoint: CGPointMake(points[i+1].x,points[i+1].y)) 
        i += 1 
       case .AddCurveToPoint: 
        pathRef.addCurveToPoint(CGPointMake(points[i].x,points[i].y), controlPoint1: CGPointMake(points[i+1].x,points[i+1].y), controlPoint2: CGPointMake(points[i+2].x,points[i+2].y)) 
        i += 2 
      default: break 
      } 
      i += 1 
     } 
     //pathRef.closePath() if you want to add new elements dont uncomment this 
     return pathRef 
    } 

このメソッドを起動したら、あなたはあなたのパスは、すべてのclosePathで洗浄し、あなたが望むように新しい行を追加する準備ができています:

は今、それはあなたの状況のパス広告HOCを再作成する時間です。

関連する問題