Cocoa勉強会201303公開用pdf

4,994 views

Published on

Cocoa勉強会201303公開用pdf

  1. 1. Bézier 2013.3.30 Cocoa勉強会 関西 大森智史 @oogon / satoshi.oomori2013年 3月 31日 日曜日
  2. 2. • スライド、サンプルは基本的にすべて公開し ます。 • 後ほどFacebookページにて2013年 3月 31日 日曜日
  3. 3. あんた、誰? • と、いうわけで自己紹介。2013年 3月 31日 日曜日
  4. 4. • 大森智史といいます。 • Objective-Cで遊んでます。 • Cocoa勉強会関西は最初からいます。2013年 3月 31日 日曜日
  5. 5. • 2/23に本が出ました。 • まさかの4000円台2013年 3月 31日 日曜日
  6. 6. • と、いうことで本題に2013年 3月 31日 日曜日
  7. 7. 今日のお話2013年 3月 31日 日曜日
  8. 8. Bézier2013年 3月 31日 日曜日
  9. 9. Bézier • こんなやつですな2013年 3月 31日 日曜日
  10. 10. ところで • iOS 6 になって、ものすごく気になるUIパー ツができました。2013年 3月 31日 日曜日
  11. 11. それは2013年 3月 31日 日曜日
  12. 12. • これです。 • びよーん。2013年 3月 31日 日曜日
  13. 13. • どうやってるのかなあ。2013年 3月 31日 日曜日
  14. 14. • じっくりと見てみることにします。2013年 3月 31日 日曜日
  15. 15. • 最初は楕円2013年 3月 31日 日曜日
  16. 16. • 下が段々小さくなっていく、上の円と下の円 の接続は曲線2013年 3月 31日 日曜日
  17. 17. • 下がさらに小さく、上も少し小さく2013年 3月 31日 日曜日
  18. 18. • さらに続く2013年 3月 31日 日曜日
  19. 19. • つまり • 上半円、下半 円、それをつ なぐ曲線 • 塗り • これでいい訳だ2013年 3月 31日 日曜日
  20. 20. • 円、曲線を書くには...2013年 3月 31日 日曜日
  21. 21. Bézier2013年 3月 31日 日曜日
  22. 22. • OS Xには、NSBezierPath、 • iOSには、UIBezierPathがある!2013年 3月 31日 日曜日
  23. 23. • 実際にやってみましょう。 • //下の半円 UIBezierPath *currentPath = [UIBezierPath bezierPath]; [currentPath addArcWithCenter: CGPointMake(200,currentPosition.y+200)     radius:100-(currentPosition.y/5) startAngle:radians(0) endAngle:radians(180) clockwise:YES];2013年 3月 31日 日曜日
  24. 24. • 度→ラジアンはマクロを作っておくと便利です。 //PIを3.14...と定義 #define PI 3.14159265358979323846 //関数定義degrees*PI/180がradians static inline double radians(double degrees) { return degrees * PI / 180; }2013年 3月 31日 日曜日
  25. 25. • ベジェパスを作る [UIBezierPath bezierPath];2013年 3月 31日 日曜日
  26. 26. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  27. 27. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  28. 28. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  29. 29. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  30. 30. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  31. 31. • 弧を描く [currentPath addArcWithCenter:中心点 radius:半径 startAngle:開始角(ラジアン) endAngle:終了角(ラジアン) clockwise:時計回りですか? ]; π 02013年 3月 31日 日曜日
  32. 32. • 次に曲線 //左側のつなぎ [currentPath addCurveToPoint:CGPointMake(100,200) controlPoint1:CGPointMake(100+ (currentPosition.y/ 5),currentPosition.y+200- (currentPosition.y/3)) controlPoint2:CGPointMake(100,200+ (currentPosition.y/5))];2013年 3月 31日 日曜日
  33. 33. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ];2013年 3月 31日 日曜日
  34. 34. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ];2013年 3月 31日 日曜日
  35. 35. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ]; 開始点2013年 3月 31日 日曜日
  36. 36. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ]; 開始点2013年 3月 31日 日曜日
  37. 37. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ]; 開始点2013年 3月 31日 日曜日
  38. 38. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ]; 開始点2013年 3月 31日 日曜日
  39. 39. • 曲線を描く [currentPath addCurveToPoint:終了点 controlPoint1:コントロールポイント1 controlPoint2:コントロールポイント2 ]; 開始点2013年 3月 31日 日曜日
  40. 40. • 同様に上半弧、右側曲線を描きます。2013年 3月 31日 日曜日
  41. 41. • パスを閉じて [currentPath closePath];2013年 3月 31日 日曜日
  42. 42. • カラーをセットして [[UIColor lightGrayColor] setFill]; • 塗ります。  [currentPath fill];2013年 3月 31日 日曜日
  43. 43. • これで、上下の移動距離に応じて弧の大きさ を変えて、曲線の長さを変えて描画します。2013年 3月 31日 日曜日
  44. 44. • DEMO • Bezier2013年 3月 31日 日曜日
  45. 45. • これだけではなんなので...2013年 3月 31日 日曜日
  46. 46. Bezierについての まめ知識 知っとくと便利2013年 3月 31日 日曜日
  47. 47. • Bézierについてのお話 2次ベジェ 3次ベジェ 角丸などに使われます。 曲線に使われます。2013年 3月 31日 日曜日
  48. 48. • Bézierについてのお話 コントロールポイント コントロールポイント C1 C2 セグメント P1 P2 アンカーポイント アンカーポイント2013年 3月 31日 日曜日
  49. 49. • Bézierについてのお話 C1 0:8 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  50. 50. • Bézierについてのお話 C1 0:8 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  51. 51. • Bézierについてのお話 C1 1:7 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  52. 52. • Bézierについてのお話 C1 2:6 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  53. 53. • Bézierについてのお話 C1 3:5 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  54. 54. • Bézierについてのお話 C1 4:4 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  55. 55. • Bézierについてのお話 C1 5:5 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  56. 56. • Bézierについてのお話 C1 6:2 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  57. 57. • Bézierについてのお話 C1 7:1 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  58. 58. • Bézierについてのお話 C1 8:0 C2 P1 P2 参考:「中学生でもわかるベジェ曲線」 http://ruiueyama.tumblr.com/post/111978822242013年 3月 31日 日曜日
  59. 59. • 三角形だから中学生でもわかりますよね。2013年 3月 31日 日曜日
  60. 60. 角の処理 マイター、ベベル2013年 3月 31日 日曜日
  61. 61. マイターリミット(ポイント接続部の角の処理) • 線幅との比率(デフォルトは10.0) • リミット値を超えるとマイター接続になります。 • (それまではベベル接続) thePath.miterLimit = 20.0; ベベル接続 マイター接続 マイター2013年 3月 31日 日曜日
  62. 62. • 線幅との比率(デフォルトは10.0) 60度なら(a:b = 1:2) a b2013年 3月 31日 日曜日
  63. 63. • DEMO • BezierMiter2013年 3月 31日 日曜日
  64. 64. 破線 ラインダッシュ2013年 3月 31日 日曜日
  65. 65. float array[5]; array[0] = 8.0; array[1] = 3.0; array[2] = 20.0; array[3] = 3.0; [outPath setLineDash: array count: 4 phase: 0.0];2013年 3月 31日 日曜日
  66. 66. • DEMO • BezierLineDash2013年 3月 31日 日曜日
  67. 67. 端の処理 ラインキャップスタイル2013年 3月 31日 日曜日
  68. 68. • lineCapStyleプロパティ • CGLineCap • kCGLineCapButt キャップなし • kCGLineCapRound 丸い端 • kCGLineCapSquare 四角2013年 3月 31日 日曜日
  69. 69. ヒットテスト その位置にパスがあるか2013年 3月 31日 日曜日
  70. 70. • - (BOOL)containsPoint:(CGPoint)point • 指定した点をパスのオブジェクト無いに含む か? • 線のセグメント上のヒットテストは後述2013年 3月 31日 日曜日
  71. 71. くりぬき 2つの処理方法2013年 3月 31日 日曜日
  72. 72. • くりぬき方法(デフォルト) • Non-Zero ルール thePath.usesEvenOddFillRule = NO;2013年 3月 31日 日曜日
  73. 73. 2013年 3月 31日 日曜日
  74. 74. 2013年 3月 31日 日曜日
  75. 75. 2013年 3月 31日 日曜日
  76. 76. 2013年 3月 31日 日曜日
  77. 77. 2013年 3月 31日 日曜日
  78. 78. 2013年 3月 31日 日曜日
  79. 79. • 参考 • パスの順序を反転する • - (UIBezierPath *)bezierPathByReversingPath NS_AVAILABLE_IOS(6_0);2013年 3月 31日 日曜日
  80. 80. • くりぬき方法 • Even-Odd ルール • ( usesEvenOddFillRuleプロパティを使用) thePath.usesEvenOddFillRule = NO;thePath.usesEvenOddFillRule = YES;2013年 3月 31日 日曜日
  81. 81. 2013年 3月 31日 日曜日
  82. 82. 2013年 3月 31日 日曜日
  83. 83. 2013年 3月 31日 日曜日
  84. 84. 2013年 3月 31日 日曜日
  85. 85. • DEMOはしませんが、サンプル置いときます • BezierNonZero • BezierEvenOdd2013年 3月 31日 日曜日
  86. 86. クリッピング 画像をマスク2013年 3月 31日 日曜日
  87. 87. • 画像のクリッピング • 画像をパスで切り抜きできます。 • [outPath2 addClip];2013年 3月 31日 日曜日
  88. 88. • 画像のクリッピング • [outPath2 addClip];2013年 3月 31日 日曜日
  89. 89. • DEMO • BezierAddclip2013年 3月 31日 日曜日
  90. 90. ブレンド 合成方法の指定2013年 3月 31日 日曜日
  91. 91. • ブレンドモード • 塗り、線で下地との混ざり具合を調整します2013年 3月 31日 日曜日
  92. 92. • ブレンドモード • [outPath3 fillWithBlendMode: (CGBlendMode)kCGBlendModeSourceAtop alpha:0.8];2013年 3月 31日 日曜日
  93. 93. • CGBlendMode kCGBlendModeNormal, kCGBlendModeSaturation, kCGBlendModeDestinationOver kCGBlendModeMultiply, kCGBlendModeColor, kCGBlendModeDestinationIn kCGBlendModeScreen, kCGBlendModeLuminosity, kCGBlendModeDestinationOut kCGBlendModeOverlay, kCGBlendModeClear, kCGBlendModeDarken, kCGBlendModeDestinationAtop kCGBlendModeCopy kCGBlendModeLighten, kCGBlendModeSourceIn kCGBlendModeXOR kCGBlendModeColorDodge, kCGBlendModeSourceOut kCGBlendModePlusDarker kCGBlendModeColorBurn, kCGBlendModeSourceAtop kCGBlendModeSoftLight, kCGBlendModePlusLighter kCGBlendModeDestinationOver kCGBlendModeHardLight, kCGBlendModeDestinationIn kCGBlendModeDifference, kCGBlendModeDestinationOut, kCGBlendModeExclusion, kCGBlendModeHue, kCGBlendModeDestinationAtop,2013年 3月 31日 日曜日
  94. 94. • DEMO • BezierBlendMode2013年 3月 31日 日曜日
  95. 95. 座標計算 パスの位置を求める2013年 3月 31日 日曜日
  96. 96. • セグメント上の座標を求める( 0 ≦ t ≦ 1 ) float tp = (1-t); CGFloat x = t*t*t*x2 + 3*t*t*tp*cp2x + 3*t*tp*tp*cp1x + tp*tp*tp*x1; CGFloat y = t*t*t*y2 + 3*t*t*tp*cp2y + 3*t*tp*tp*cp1y + tp*tp*tp*y1; t=1 ここはどこ? t=02013年 3月 31日 日曜日
  97. 97. • DEMO • BezierSegmentPoint2013年 3月 31日 日曜日
  98. 98. 接線の角度 ある地点の傾き2013年 3月 31日 日曜日
  99. 99. • 接線の角度を求める( 0 ≦ t ≦ 1 ) float tp = (1-t); CGFloat dx = 3*(t*t*(x2-cp2x)+2*t*tp*(cp2x-cp1x)+tp*tp*(cp1x- x1)); CGFloat dy = 3*(t*t*(y2-cp2y)+2*t*tp*(cp2y-cp1y)+tp*tp*(cp1y- y1)); NSLog(@"%.2f,(%.2f,%.2f)",degrees(atan2(dy,dx)),dx,dy); t=1 ラジアンを度に変換してい るマクロ関数 0° t=02013年 3月 31日 日曜日
  100. 100. • DEMO • BezierSegmentIncline2013年 3月 31日 日曜日
  101. 101. パスの変形 アフィン変換2013年 3月 31日 日曜日
  102. 102. • パスに沿って文字を描画。 • グリフとグリフから取ったパス、両方で描画していま す。2013年 3月 31日 日曜日
  103. 103. グリフのパス取得はソースを見てね パスの変形 CGAffineTransform affine = CGAffineTransformMakeTranslation(x,y); affine = CGAffineTransformRotate(affine, atan2(dy,dx)); [glyphBezierPath applyTransform:affine];2013年 3月 31日 日曜日
  104. 104. • DEMO • BezierSegmentInclineString2013年 3月 31日 日曜日
  105. 105. ヒットテスト セグメント上で2013年 3月 31日 日曜日
  106. 106. • 任意の点から一番近いポイントを求める。 • 計算でできるみたいなんだけど、よくわからなかった ので、t=0からt=1までのセグメント上の点の位置を計 算して、セグメント上の距離を比較してみました。2013年 3月 31日 日曜日
  107. 107. • 線上でのヒットテストに使うことができます2013年 3月 31日 日曜日
  108. 108. • DEMO • BezierSegmentNearPoint2013年 3月 31日 日曜日
  109. 109. パスの分割2013年 3月 31日 日曜日
  110. 110. • パスの分割 • 2の位置で分割する(0 ≦ t1 ≦ 1, 0 ≦ t2 ≦ 1, t1 < t2) 2 12013年 3月 31日 日曜日
  111. 111. • パスの分割 double t1p = 1-t1; double t2p = 1-t2; double newx1 = t1p*t1p*t1p*x1 + 3*t1*t1p*t1p*cp1x + 3*t1*t1*t1p*cp2x + t1*t1*t1*x2; double newy1 = t1p*t1p*t1p*y1 + 3*t1*t1p*t1p*cp1y + 3*t1*t1*t1p*cp2y + t1*t1*t1*y2; double newcp1x = t1p*t1p*(t2p*x1+t2*cp1x) + 2*t1p*t1*(t2p*cp1x+t2*cp2x) + t1*t1*(t2p*cp2x+t2*x2); double newcp1y = t1p*t1p*(t2p*y1+t2*cp1y) + 2*t1p*t1*(t2p*cp1y+t2*cp2y) + t1*t1*(t2p*cp2y+t2*y2); double newcp2x = t2p*t2p*(t1p*x1+t1*cp1x) + 2*t2p*t2*(t1p*cp1x+t1*cp2x) + t2*t2*(t1p*cp2x+t1*x2); double newcp2y = t2p*t2p*(t1p*y1+t1*cp1y) + 2*t2p*t2*(t1p*cp1y+t1*cp2y) + t2*t2*(t1p*cp2y+t1*y2); double newx2 = t2p*t2p*t2p*x1 + 3*t2*t2p*t2p*cp1x + 3*t2*t2*t2p*cp2x + t2*t2*t2*x2; double newy2 = t2p*t2p*t2p*y1 + 3*t2*t2p*t2p*cp1y + 3*t2*t2*t2p*cp2y + t2*t2*t2*y2; t2 newcp2 newcp1 t1 2 12013年 3月 31日 日曜日
  112. 112. • DEMO • BezierSplit2013年 3月 31日 日曜日
  113. 113. 最後に2013年 3月 31日 日曜日
  114. 114. • 最初は取っ付きにくいですが、慣れるといろ いろ自由な曲線を書くことができます。 • いろいろ試してみてください。2013年 3月 31日 日曜日
  115. 115. • ありがとうございました。2013年 3月 31日 日曜日
  116. 116. • ありがとうございました。2013年 3月 31日 日曜日

×