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
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
140
Swift on Linux
subdigital
1
880
tvOS Workshop
subdigital
1
160
Swift Solutions
subdigital
2
480
iOS 8 Networking
subdigital
4
950
iOS 8 App Extensions
subdigital
1
380
Effective Networking with iOS 8 and Swift
subdigital
4
1.7k
Other Decks in Programming
See All in Programming
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
440
Apache Iceberg V3 and migration to V3
tomtanaka
0
220
Event Storming
hschwentner
3
1.3k
生成AIを活用したソフトウェア開発ライフサイクル変革の現在値
hiroyukimori
PRO
0
140
生成AIを使ったコードレビューで定性的に品質カバー
chiilog
1
310
DSPy入門 Pythonで実現する自動プロンプト最適化 〜人手によるプロンプト調整からの卒業〜
seaturt1e
1
260
今更考える「単一責任原則」 / Thinking about the Single Responsibility Principle
tooppoo
2
940
FOSDEM 2026: STUNMESH-go: Building P2P WireGuard Mesh Without Self-Hosted Infrastructure
tjjh89017
0
190
AIプロダクト時代のQAエンジニアに求められること
imtnd
1
480
AIエージェントのキホンから学ぶ「エージェンティックコーディング」実践入門
masahiro_nishimi
7
1.2k
受け入れテスト駆動開発(ATDD)×AI駆動開発 AI時代のATDDの取り組み方を考える
kztakasaki
2
430
Rails Girls Tokyo 18th GMO Pepabo Sponsor Talk
yutokyokutyo
0
170
Featured
See All Featured
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
61k
Technical Leadership for Architectural Decision Making
baasie
2
270
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.2k
Believing is Seeing
oripsolob
1
67
Abbi's Birthday
coloredviolet
2
5k
Amusing Abliteration
ianozsvald
0
120
XXLCSS - How to scale CSS and keep your sanity
sugarenia
249
1.3M
How to build an LLM SEO readiness audit: a practical framework
nmsamuel
1
660
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
930
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
2.7k
The Language of Interfaces
destraynor
162
26k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
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! ステッカーが欲しかったら話 しかけてください!