Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Bézier Curves
Search
Ben Scheirman
March 02, 2018
Programming
5.6k
1
Share
Bézier Curves
Presented at try! Swift Tokyo 2018
Ben Scheirman
March 02, 2018
More Decks by Ben Scheirman
See All by Ben Scheirman
A Promise for a Better Future
subdigital
0
190
Buckets of Code
subdigital
0
2k
Building 5 Calls for iOS
subdigital
0
150
Swift on Linux
subdigital
1
900
tvOS Workshop
subdigital
1
180
Swift Solutions
subdigital
2
490
iOS 8 Networking
subdigital
4
970
iOS 8 App Extensions
subdigital
1
390
Effective Networking with iOS 8 and Swift
subdigital
4
1.7k
Other Decks in Programming
See All in Programming
TSKaigi2026-静的解析への投資がAI時代のコード品質を支える ── カスタムESLintルールの設計と運用
hayatokudou
7
1.3k
Technical Debt: Understanding it Rightly, Engaging it Rightly #LaravelLiveJP
shogogg
0
180
Augmenting AI with the Power of Jakarta EE
ivargrimstad
0
410
ReactとSvelteのその先、Ripple-TS / Beyond React and Svelte: Ripple-TS
ssssota
3
1.8k
Stage 3 Decorators でできること / できないこと / TSKaigi 2026
susisu
1
1.4k
1人1案件のプロダクトエンジニア時代に、"プロセス監督"としてチャレンジしたこと
non0113
0
360
サーバーレスで作る、動画データ管理基盤
oyasumipants
0
320
プロパティの順序で型推論が壊れる!? TypeScript6.0の修正からContext-Sensitivityの仕組みを追う
bicstone
2
1.3k
Why Laravel apps break—Mastering the fundamentals to keep them maintainable
kentaroutakeda
1
320
初めてのRubyKaigiはこう見えた
jellyfish700
0
370
These Five Tricks Can Make Your Apps Greener, Cheaper, & Nicer
hollycummins
0
250
権限チェックの一貫性を型で守る TypeScript による多層防御
mnch
4
990
Featured
See All Featured
DevOps and Value Stream Thinking: Enabling flow, efficiency and business value
helenjbeal
1
210
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
1
2.7k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.5k
ラッコキーワード サービス紹介資料
rakko
1
3.5M
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
12
1.2k
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2k
Lightning talk: Run Django tests with GitHub Actions
sabderemane
0
190
For a Future-Friendly Web
brad_frost
183
10k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
GraphQLとの向き合い方2022年版
quramy
50
15k
Unsuck your backbone
ammeep
672
58k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
150
Transcript
Bézier Curves Ben Scheirman nsscreencast.com @subdigital
None
None
None
let path = UIBezierPath() path.move(to: startPoint) path.addCurve(to: endPoint, controlPoint1: c1,
controlPoint2: c2) context.addPath(path.cgPath) context.strokePath()
Control points?!
Paul de Casteljau
None
None
None
None
None
None
None
None
None
None
None
None
class BezierView : UIView { var startPoint: CGPoint? var endPoint:
CGPoint? var control1: CGPoint? var control2: CGPoint? ...
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() }
Demo
class BezierView : UIView { var startPoint: CGPoint? var endPoint:
CGPoint? var control1: CGPoint? var control2: CGPoint? ...
class BezierView : UIView { var points: [CGPoint] ...
if points.count >= 2 { drawLinesBetween(context, points) }
func drawLinesBetween(_ context: CGContext, _ points: [CGPoint]) { }
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() }
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() }
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() }
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) } }
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) } }
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) } }
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) } }
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) } }
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) } }
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) } }
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) } }
zip(sequence1, sequence2)
sequence1 Sequence2
sequence1 Sequence2 zip
sequence1 Sequence2 zip
sequence1 Sequence2 P1 P2 P3 P4 P5 P2 P3 P4
P5 zip
sequence1 Sequence2 P1 P2 P3 P4 P5 P2 P3 P4
P5 zip
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) } } }
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) } } }
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) } } }
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) } } }
None
Rapid Feedback
Explore! Experiment!
Thank you ! Ben Scheirman nsscreencast.com @subdigital
Thank you ! Ben Scheirman nsscreencast.com @subdigital Ask me for
a sticker! ステッカーが欲しかったら話 しかけてください!
Thank you ! Ben Scheirman nsscreencast.com @subdigital Ask me for
a sticker! ステッカーが欲しかったら話 しかけてください!