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.7k
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
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
200
Buckets of Code
subdigital
0
2k
Building 5 Calls for iOS
subdigital
0
160
Swift on Linux
subdigital
1
910
tvOS Workshop
subdigital
1
190
Swift Solutions
subdigital
2
500
iOS 8 Networking
subdigital
4
980
iOS 8 App Extensions
subdigital
1
400
Effective Networking with iOS 8 and Swift
subdigital
4
1.7k
Other Decks in Programming
See All in Programming
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
220
「寝てても仕事が進む」Claude Codeで組む第二の脳
tomoyafujita2016
0
290
生成AI導入の「期待外れ」を乗り越える ー 開発フロー改革が目指す、真の組織変革
starfish719
0
3.9k
Foundation Models frameworkで画像分析
ryodeveloper
1
510
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
1.7k
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
230
PHP Application における Kubernetes 内 gRPC 通信
ganchiku
0
580
作るコストが小さくなった時代 幸せに働くために改めて考えたいこと 〜エンジニアとして価値を出し続けるために注視している二分野〜
yuppeeng
0
180
自動化したのに回らないテスト運用の壁ーAI時代の品質責任と生産性
mfunaki
0
120
Detecting Compromised CI with eBPF and Cilium Tetragon
lizrice
0
130
数百円から始めるRuby電子工作
tarosay
0
130
ルールを書いて終わらせないハーネスエンジニアリング
yug1224
4
1.8k
Featured
See All Featured
[SF Ruby Conf 2025] Rails X
palkan
2
1.2k
The Impact of AI in SEO - AI Overviews June 2024 Edition
aleyda
5
1.1k
Practical Orchestrator
shlominoach
191
12k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
232
55k
Deep Space Network (abreviated)
tonyrice
0
250
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
460
The Illustrated Children's Guide to Kubernetes
chrisshort
51
53k
SEOcharity - Dark patterns in SEO and UX: How to avoid them and build a more ethical web
sarafernandez
0
230
A Modern Web Designer's Workflow
chriscoyier
698
190k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Building AI with AI
inesmontani
PRO
1
1.1k
Prompt Engineering for Job Search
mfonobong
0
390
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! ステッカーが欲しかったら話 しかけてください!