Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Bézier Curves
Search
Ben Scheirman
March 02, 2018
Programming
1
5.5k
Bézier Curves
Presented at try! Swift Tokyo 2018
Ben Scheirman
March 02, 2018
Tweet
Share
More Decks by Ben Scheirman
See All by Ben Scheirman
A Promise for a Better Future
subdigital
0
170
Buckets of Code
subdigital
0
2k
Building 5 Calls for iOS
subdigital
0
130
Swift on Linux
subdigital
1
870
tvOS Workshop
subdigital
1
160
Swift Solutions
subdigital
2
470
iOS 8 Networking
subdigital
4
940
iOS 8 App Extensions
subdigital
1
370
Effective Networking with iOS 8 and Swift
subdigital
4
1.7k
Other Decks in Programming
See All in Programming
組み合わせ爆発にのまれない - 責務分割 x テスト
halhorn
1
160
エディターってAIで操作できるんだぜ
kis9a
0
750
Canon EOS R50 V と R5 Mark II 購入でみえてきた最近のデジイチ VR180 事情、そして VR180 静止画に活路を見出すまで
karad
0
130
著者と進める!『AIと個人開発したくなったらまずCursorで要件定義だ!』
yasunacoffee
0
150
Context is King? 〜Verifiability時代とコンテキスト設計 / Beyond "Context is King"
rkaga
10
1.4k
TestingOsaka6_Ozono
o3
0
170
Patterns of Patterns
denyspoltorak
0
250
ローカルLLMを⽤いてコード補完を⾏う VSCode拡張機能を作ってみた
nearme_tech
PRO
0
140
新卒エンジニアのプルリクエスト with AI駆動
fukunaga2025
0
230
AIコーディングエージェント(skywork)
kondai24
0
200
脳の「省エネモード」をデバッグする ~System 1(直感)と System 2(論理)の切り替え~
panda728
PRO
0
120
AI Agent Dojo #4: watsonx Orchestrate ADK体験
oniak3ibm
PRO
0
110
Featured
See All Featured
More Than Pixels: Becoming A User Experience Designer
marktimemedia
2
250
Bash Introduction
62gerente
615
210k
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
0
320
Balancing Empowerment & Direction
lara
5
820
Highjacked: Video Game Concept Design
rkendrick25
PRO
0
240
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
0
31
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
86
Done Done
chrislema
186
16k
Evolving SEO for Evolving Search Engines
ryanjones
0
73
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
1
260
Producing Creativity
orderedlist
PRO
348
40k
Thoughts on Productivity
jonyablonski
73
5k
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! ステッカーが欲しかったら話 しかけてください!