Bézier Curves

Bézier Curves

Presented at try! Swift Tokyo 2018

023a6a37e8177cb2f84a236bbce643cf?s=128

Ben Scheirman

March 02, 2018
Tweet

Transcript

  1. Bézier Curves Ben Scheirman nsscreencast.com @subdigital

  2. None
  3. None
  4. None
  5. let path = UIBezierPath() path.move(to: startPoint) path.addCurve(to: endPoint, controlPoint1: c1,

    controlPoint2: c2) context.addPath(path.cgPath) context.strokePath()
  6. Control points?!

  7. Paul de Casteljau

  8. None
  9. None
  10. None
  11. None
  12. None
  13. None
  14. None
  15. None
  16. None
  17. None
  18. None
  19. None
  20. class BezierView : UIView { var startPoint: CGPoint? var endPoint:

    CGPoint? var control1: CGPoint? var control2: CGPoint? ...
  21. func drawPoint(_ context: CGContext, p: CGPoint, color: UIColor, radius: CGFloat)

    { color.setFill() context.addArc(center: p, radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true) context.fillPath() }
  22. Demo

  23. class BezierView : UIView { var startPoint: CGPoint? var endPoint:

    CGPoint? var control1: CGPoint? var control2: CGPoint? ...
  24. class BezierView : UIView { var points: [CGPoint] ...

  25. if points.count >= 2 { drawLinesBetween(context, points) }

  26. func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { }

  27. func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { points.first.flatMap {

    context.move(to: $0) } points.dropFirst().forEach { context.addLine(to: $0 ) } context.setLineWidth(3) context.setLineDash(phase: 0, lengths: [2]) UIColor.lightGray.setStroke() context.strokePath() }
  28. func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { points.first.flatMap {

    context.move(to: $0) } points.dropFirst().forEach { context.addLine(to: $0 ) } context.setLineWidth(3) context.setLineDash(phase: 0, lengths: [2]) UIColor.lightGray.setStroke() context.strokePath() }
  29. func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { points.first.flatMap {

    context.move(to: $0) } points.dropFirst().forEach { context.addLine(to: $0 ) } context.setLineWidth(3) context.setLineDash(phase: 0, lengths: [2]) UIColor.lightGray.setStroke() context.strokePath() }
  30. func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { points.first.flatMap {

    context.move(to: $0) } points.dropFirst().forEach { context.addLine(to: $0 ) } context.setLineWidth(3) context.setLineDash(phase: 0, lengths: [2]) UIColor.lightGray.setStroke() context.strokePath() if timeValue > 0 { interpolateBetween(context, points) } }
  31. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  32. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  33. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  34. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  35. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  36. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } }
  37. func interpolateBetween(_ context: CGContext, _ points: [CGPoint]) { guard points.count

    >= 2 else { return } var interpolated: [CGPoint] = [] for i in 0 ..< points.count-1 { let p1 = points[i] let p2 = points[i+1] let t = p1.lerp(p2, t: timeValue) interpolated.append(t) drawPoint(context, p: t, color: .lightGray, radius: 6) } if interpolated.count >= 2 { drawLinesBetween(context, interpolated) } }
  38. zip(sequence1, sequence2)

  39. sequence1 Sequence2

  40. sequence1 Sequence2 zip

  41. sequence1 Sequence2 zip

  42. sequence1 Sequence2 P1 P2 P3 P4 P5 P2 P3 P4

    P5 zip
  43. sequence1 Sequence2 P1 P2 P3 P4 P5 P2 P3 P4

    P5 zip
  44. func interpZip(points: [CGPoint]) -> (CGFloat) -> [CGPoint] { return {

    t in let pairs = zip(points, points.dropFirst()) return pairs.map { pair in return lerp(pair.0, pair.1, t) } } }
  45. func interpZip(points: [CGPoint]) -> (CGFloat) -> [CGPoint] { return {

    t in let pairs = zip(points, points.dropFirst()) return pairs.map { pair in return lerp(pair.0, pair.1, t) } } }
  46. func interpZip(points: [CGPoint]) -> (CGFloat) -> [CGPoint] { return {

    t in let pairs = zip(points, points.dropFirst()) return pairs.map { pair in return lerp(pair.0, pair.1, t) } } }
  47. func interpZip(points: [CGPoint]) -> (CGFloat) -> [CGPoint] { return {

    t in let pairs = zip(points, points.dropFirst()) return pairs.map { pair in return pair.0.lerp(pair.1, t: timeValue) } } }
  48. None
  49. Rapid Feedback

  50. Explore! Experiment!

  51. Thank you ! Ben Scheirman nsscreencast.com @subdigital

  52. Thank you ! Ben Scheirman nsscreencast.com @subdigital Ask me for

    a sticker! ステッカーが欲しかったら話 しかけてください!
  53. Thank you ! Ben Scheirman nsscreencast.com @subdigital Ask me for

    a sticker! ステッカーが欲しかったら話 しかけてください!