Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Swift
by Ray Fix for iOSDC
Ray Fix
Photo by Renato Sanchez Lozada on Unsplash
iOSDC 

RayWenderlich.com
Ray Ray Wenderlich 😉
REVOLVE
REVOLVE
Swift
Swift Python R
•
• Swift
•
• Swift
•
• Swift
WWDC 2017 — fox2
https://developer.apple.com/videos/play/wwdc2017/604/
WWDC 2017 — fox2
https://developer.apple.com/videos/play/wwdc2017/604/
WWDC 2017 — ARKit
https://developer.apple.com/videos/play/wwdc2017/602/
WWDC 2017 — ARKit
https://developer.apple.com/videos/play/wwdc2017/602/
Fall 2017 — ARFaceAnchor
https://developer.apple.com/documentation/arkit/arfaceanchor?changes=latest_beta
I❤Swift
I❤Swift
https://github.com/rayfix/TypedTransforms
degrees radians
protocol AngleProtocol {
}
associatedtype TT
protocol AngleProtocol {
}
associatedtype T
protocol AngleProtocol {
}
associatedtype Real
protocol AngleProtocol {
}
associatedtype Real : FloatingPoint
AngleProtocol
protocol AngleProtocol {
associatedtype Real: FloatingPoint
init(radians: Real)
var radians: Real { set get ...
(1)
extension AngleProtocol {
}
(1)
extension AngleProtocol {
}
static func +(lhs: Self, rhs: Self) -> Self {
return Self(radians: lhs.radians + rhs.radia...
(1)
extension AngleProtocol {
}
static func +=(lhs: inout Self, rhs: Self) {
lhs = lhs + rhs
}
static func +(lhs: Self, rh...
(2)
extension AngleProtocol {
}
(2)
extension AngleProtocol {
}
static prefix func -(angle: Self) -> Self {
return Self(radians: -angle.radians)
}
(2)
extension AngleProtocol {
}
static prefix func -(angle: Self) -> Self {
return Self(radians: -angle.radians)
}
static ...
(2)
extension AngleProtocol {
}
static prefix func -(angle: Self) -> Self {
return Self(radians: -angle.radians)
}
static ...
(3)
extension AngleProtocol {
}
(3)
extension AngleProtocol {
}
static func *(multiple: Real, angle: Self) -> Self {
return Self(radians: multiple * angle...
(3)
extension AngleProtocol {
}
static func *(multiple: Real, angle: Self) -> Self {
return Self(radians: multiple * angle...
(3)
extension AngleProtocol {
}
static func *(multiple: Real, angle: Self) -> Self {
return Self(radians: multiple * angle...
extension AngleProtocol: Hashable, Comparable {
} Stepanov, Alexander; McJones, Paul (2009). Elements of Programming. Addi...
extension AngleProtocol: Hashable, Comparable {
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.radians == rhs...
extension AngleProtocol: Hashable, Comparable {
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.radians == rhs...
extension AngleProtocol: Hashable, Comparable {
}
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs.radians == rhs...
protocol AngleDegreesConvertible: AngleProtocol {
init(degrees: Real)
var degrees: Real { set get }
static var radiansToDe...
(1)
extension AngleDegreesConvertible {
var degrees: Real {
get {
return radians * Self.radiansToDegrees
}
}
}
(1)
extension AngleDegreesConvertible {
var degrees: Real {
get {
return radians * Self.radiansToDegrees
}
}
}
radiansToDe...
(1)
extension AngleDegreesConvertible {
var degrees: Real {
get {
return radians * Self.radiansToDegrees
}
}
}
radiansToDe...
(1)
extension AngleDegreesConvertible {
var degrees: Real {
get {
return radians * Self.radiansToDegrees
}
}
}
radiansToDe...
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
Inverse Transform
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
ToDegreesradians
Inverse Transform
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
ToDegrees radians
Inverse Transform
Radian...
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
init(degrees: Real) {
let degreesToRadians...
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
init(degrees: Real) {
let degreesToRadians...
(2)
init(degrees: Real) {
self.init(radians: degrees * Self.radiansToDegrees)
}
init(degrees: Real) {
let degreesToRadians...
var degrees: Real {
set(newDegrees) {
let degreesToRadians = 1 / Self.radiansToDegrees
radians = newDegrees * degreesToRad...
var degrees: Real {
set(newDegrees) {
let degreesToRadians = 1 / Self.radiansToDegrees
radians = newDegrees * degreesToRad...
var degrees: Real {
set(newDegrees) {
let degreesToRadians = 1 / Self.radiansToDegrees
radians = newDegrees * degreesToRad...
To
🐶
🐕
🐩 😸
🐈
😽
To
🐶
🐕
🐩 😸
🐈
😽
To
🐶
🐕
🐩😸
🐈
😽
protocol AngleProtocol {
associatedtype Real:
init(radians: Real)
var radians: Real { set get }
}
FloatingPoint
protocol AngleProtocol {
associatedtype Real:
init(radians: Real)
var radians: Real { set get }
}
FloatingPoint
protocol AngleProtocol {
associatedtype Real:
init(radians: Real)
var radians: Real { set get }
}
TrigonometricFloatingPoi...
protocol AngleProtocol {
associatedtype Real:
init(radians: Real)
var radians: Real { set get }
}
TrigonometricFloatingPoi...
sin
sin
func sin(_ angle: AngleProtocol) -> ???? {
}
sin
func sin(_ angle: AngleProtocol) -> ???? {
}
sin
func sin<A: AngleProtocol>(_ angle: A) -> A.Real {
return A.Real.sine(radians: angle.radians)
}
func sin(_ angle: Angl...
CGAngle
struct CGAngle: AngleDegreesConvertible {
var radians: CGFloat
static var radiansToDegrees: CGFloat {
return 180/C...
CGAngle
struct CGAngle: AngleDegreesConvertible {
var radians: CGFloat
static var radiansToDegrees: CGFloat {
return 180/C...
protocol Point2DProtocol {
associatedtype Scalar: FloatingPoint
init(_ x: Scalar, _ y: Scalar)
var x: Scalar { get set }
v...
…
static func +(lhs: Self, rhs: Self) -> Self {
return Self(lhs.x + rhs.x, lhs.y + rhs.y)
}
static prefix func -(p: Self) ...
…
extension Point2DProtocol {
}
var lengthSquared: Scalar {
return self*self
}
var length: Scalar {
return lengthSquared.s...
extension CGPoint: Point2DProtocol {
public init(_ x: CGFloat, _ y: CGFloat) {
self.x = x
self.y = y
}
}
💯
let newPoint = transform * point
[ ]a
db
c
[x
y
]=[ax + cy
]bx + dy
let newPoint = transform * point
[ ]a
db
c
1
tx
ty
0 0 [x
y
1 ]=[ax + cy + tx
1 ]bx + dy + ty
CGAffineTransform
CGAffineTransform
Think Different
CGAffineTransform
Think Different
][ax + cy + tx 1bx + dy + ty
[ ]a
d
b
c
1tx ty
0
0
[x y 1
]=
let newPoint = transform * point
][ax + cy + tx 1bx + dy + ty
[ ]a
d
b
c
1tx ty
0
0
[x y 1
]=
let newPoint = transform * point
][ax + cy + tx 1bx + dy + ty
[ ]a
d
b
c
1tx ty
0
0
[x y 1
]=
let newPoint = transform * point
let newPoint = point * transform
][ax + cy + tx 1bx + dy + ty
[ ]a
d
b
c
1tx ty
0
0
[x y ...
A
C
(0, 0)
A
C
(7, 7)
xa = (7, 7)
(0, 0)
A
C
(7, 7)
yc = xa * aToC
xa = (7, 7)
(0, 0)
A
C
(7, 7)
(1,0)
yc = xa * aToC
xa = (7, 7)
yc == (1, 0)
(0, 0)
A
C
(7, 7)
(1,0)
yc = xa * aToC
xa = (7, 7)
yc == (1, 0)
yc * aToC
(0, 0)
A
C
(7, 7)
(1,0)
yc = xa * aToC
xa = (7, 7)
yc == (1, 0)
yc * aToC
(0, 0)
A
A
B
A
C
A
C
aToB * bToC
A
C
aToB * bToC
aToC
=
[ ]1
10
0
1
0
0
tx ty [ ]sx
sy0
0
1
0
0
0 0 [ ]
cos a
cos a-sin a
sin a
1
0
0
0 0
translation scale rotation
[ ]1
10
0
1
0...
ctm
[ ]2
-20
0
1
0
0
0 1096
userToDevice
CGAffineTransform
extension CGAffineTransform {
static func *(point: CGPoint, transform: CGAffineTransform)
-> CGPoint
{
re...
2
let house: [CGPoint] = [CGPoint(1,-1),
CGPoint(1,1),
CGPoint(0,2),
CGPoint(-1,1),
CGPoint(-1,-1)]
2
let house: [CGPoint] = [CGPoint(1,-1),
CGPoint(1,1),
CGPoint(0,2),
CGPoint(-1,1),
CGPoint(-1,-1)]
context.saveGState()
d...
2
let modelToUser =
CGAffineTransform(scaleX: 1, y: -1) *
CGAffineTransform(scaleX: 100, y: 100) *
CGAffineTransform(trans...
2
let modelToUser =
CGAffineTransform(scaleX: 1, y: -1) *
CGAffineTransform(scaleX: 100, y: 100) *
CGAffineTransform(trans...
2
context.move(to: house.first!)
house.dropFirst().forEach { context.addLine(to: $0)}
context.closePath()
context.strokePa...
protocol CoordinateSpace {}
enum ModelSpace: CoordinateSpace {}
enum UserSpace: CoordinateSpace {}
enum DeviceSpace: Coord...
struct CGPointT<Space: CoordinateSpace>: Point2DProtocol {
var xy: CGPoint
:
}
let house: [CGPointT<ModelSpace>] = [CGPoin...
struct CGAffineTransformT<From: CoordinateSpace,
To: CoordinateSpace>
{
var matrix: CGAffineTransform
public func inverted...
struct CGAffineTransformT<From: CoordinateSpace,
To: CoordinateSpace>
{
var matrix: CGAffineTransform
public func inverted...
To
🐶
🐕
🐩 😸
🐈
😽
To
🐶
🐕
🐩 😸
🐈
😽
To
😸
🐈
😽
To
😸
🐈
😽
ARKit 3
SIMD
[ ]matrix_float4x4
[ ]float4
post multiply To
[ ]float4
ARKit 3
From
worldFromCameralet worldPoint = * cameraPoint
float4_t
struct float4_t<Space: CoordinateSpace> {
var point: float4
init(_ point: float4) {
self.point = point
}
}
matrix_float4x4_t
struct matrix_float4x4_t<To: CoordinateSpace,
From: CoordinateSpace> {
var matrix: matrix_float4x4
init(_...
extension matrix_float4x4_t {
static func *<To, From>(lhs: matrix_float4x4_t<To, From>,
rhs: float4_t<From>) -> float4_t<T...
transform
transform
transform
cameraFromWorld
worldFromCamera
transform
cameraFromWorld
worldFromCamera
final class TypedTransforms<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
final class TypedTransforms<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol TypedTransformAdditi...
final class TypedTransforms<Base> {
let base: Base
init(_ base: Base) {
self.base = base
}
}
protocol TypedTransformAdditi...
extension ARCamera: TypedTransformAdditions {}
extension TypedTransforms where Base: ARCamera {
var worldFromCamera: matrix_float4x4_t<WorldSpace,
CameraSpace>
{
return ...
let worldFromCamera =
frame.camera.typed.worldFromCamera
let shotDirectionCamera =
float4_t<CameraSpace>(float4(0, 0, -3, 1))
let shotDirectionWorld = worldFromCamera *
shotDirect...
let position =
SCNVector3(float4: worldFromCamera.matrix.columns.3)
[ ]
matrix_float4x4
tx
ty
tz
1
0 21 3
let ball = Ball()
ball.position = position
ball.physicsBody?.applyForce(direction,
asImpulse: true)
sceneView.scene.rootNo...
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
視覚化とSwiftのタイプについて
Upcoming SlideShare
Loading in …5
×

視覚化とSwiftのタイプについて

803 views

Published on

Presentation for iOSDC 2017

Published in: Software
  • Be the first to comment

  • Be the first to like this

視覚化とSwiftのタイプについて

  1. 1. Swift by Ray Fix for iOSDC
  2. 2. Ray Fix Photo by Renato Sanchez Lozada on Unsplash iOSDC 

  3. 3. RayWenderlich.com Ray Ray Wenderlich 😉
  4. 4. REVOLVE
  5. 5. REVOLVE
  6. 6. Swift
  7. 7. Swift Python R
  8. 8. • • Swift
  9. 9. • • Swift
  10. 10. • • Swift
  11. 11. WWDC 2017 — fox2 https://developer.apple.com/videos/play/wwdc2017/604/
  12. 12. WWDC 2017 — fox2 https://developer.apple.com/videos/play/wwdc2017/604/
  13. 13. WWDC 2017 — ARKit https://developer.apple.com/videos/play/wwdc2017/602/
  14. 14. WWDC 2017 — ARKit https://developer.apple.com/videos/play/wwdc2017/602/
  15. 15. Fall 2017 — ARFaceAnchor https://developer.apple.com/documentation/arkit/arfaceanchor?changes=latest_beta
  16. 16. I❤Swift
  17. 17. I❤Swift https://github.com/rayfix/TypedTransforms
  18. 18. degrees radians
  19. 19. protocol AngleProtocol { } associatedtype TT
  20. 20. protocol AngleProtocol { } associatedtype T
  21. 21. protocol AngleProtocol { } associatedtype Real
  22. 22. protocol AngleProtocol { } associatedtype Real : FloatingPoint
  23. 23. AngleProtocol protocol AngleProtocol { associatedtype Real: FloatingPoint init(radians: Real) var radians: Real { set get } }
  24. 24. (1) extension AngleProtocol { }
  25. 25. (1) extension AngleProtocol { } static func +(lhs: Self, rhs: Self) -> Self { return Self(radians: lhs.radians + rhs.radians) }
  26. 26. (1) extension AngleProtocol { } static func +=(lhs: inout Self, rhs: Self) { lhs = lhs + rhs } static func +(lhs: Self, rhs: Self) -> Self { return Self(radians: lhs.radians + rhs.radians) }
  27. 27. (2) extension AngleProtocol { }
  28. 28. (2) extension AngleProtocol { } static prefix func -(angle: Self) -> Self { return Self(radians: -angle.radians) }
  29. 29. (2) extension AngleProtocol { } static prefix func -(angle: Self) -> Self { return Self(radians: -angle.radians) } static func -(lhs: Self, rhs: Self) -> Self { return lhs+(-rhs) }
  30. 30. (2) extension AngleProtocol { } static prefix func -(angle: Self) -> Self { return Self(radians: -angle.radians) } static func -(lhs: Self, rhs: Self) -> Self { return lhs+(-rhs) } static func -=(lhs: inout Self, rhs: Self) { lhs = lhs - rhs }
  31. 31. (3) extension AngleProtocol { }
  32. 32. (3) extension AngleProtocol { } static func *(multiple: Real, angle: Self) -> Self { return Self(radians: multiple * angle.radians) }
  33. 33. (3) extension AngleProtocol { } static func *(multiple: Real, angle: Self) -> Self { return Self(radians: multiple * angle.radians) } static func *(angle: Self, multiple: Real) -> Self { return multiple * angle }
  34. 34. (3) extension AngleProtocol { } static func *(multiple: Real, angle: Self) -> Self { return Self(radians: multiple * angle.radians) } static func *(angle: Self, multiple: Real) -> Self { return multiple * angle } static func /(angle: Self, divisor: Real) -> Self { return angle * (1/divisor) }
  35. 35. extension AngleProtocol: Hashable, Comparable { } Stepanov, Alexander; McJones, Paul (2009). Elements of Programming. Addison-Wesley. ISBN 978-0-321-63537-2.
  36. 36. extension AngleProtocol: Hashable, Comparable { } static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.radians == rhs.radians } Stepanov, Alexander; McJones, Paul (2009). Elements of Programming. Addison-Wesley. ISBN 978-0-321-63537-2.
  37. 37. extension AngleProtocol: Hashable, Comparable { } static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.radians == rhs.radians } var hashValue: Int { return radians.hashValue } Stepanov, Alexander; McJones, Paul (2009). Elements of Programming. Addison-Wesley. ISBN 978-0-321-63537-2.
  38. 38. extension AngleProtocol: Hashable, Comparable { } static func ==(lhs: Self, rhs: Self) -> Bool { return lhs.radians == rhs.radians } var hashValue: Int { return radians.hashValue } static func <(lhs: Self, rhs: Self) -> Bool { return lhs.radians < rhs.radians } Stepanov, Alexander; McJones, Paul (2009). Elements of Programming. Addison-Wesley. ISBN 978-0-321-63537-2.
  39. 39. protocol AngleDegreesConvertible: AngleProtocol { init(degrees: Real) var degrees: Real { set get } static var radiansToDegrees: Real { get } }
  40. 40. (1) extension AngleDegreesConvertible { var degrees: Real { get { return radians * Self.radiansToDegrees } } }
  41. 41. (1) extension AngleDegreesConvertible { var degrees: Real { get { return radians * Self.radiansToDegrees } } } radiansToDegrees
  42. 42. (1) extension AngleDegreesConvertible { var degrees: Real { get { return radians * Self.radiansToDegrees } } } radiansToDegrees radiansToDegreesradians
  43. 43. (1) extension AngleDegreesConvertible { var degrees: Real { get { return radians * Self.radiansToDegrees } } } radiansToDegrees radiansToDegrees degrees
  44. 44. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) }
  45. 45. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) }
  46. 46. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } Inverse Transform
  47. 47. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } ToDegreesradians Inverse Transform
  48. 48. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } ToDegrees radians Inverse Transform Radiansdegrees
  49. 49. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) }
  50. 50. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) }
  51. 51. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } init(degrees: Real) { let degreesToRadians = 1 / Self.radiansToDegrees self.init(radians: degrees * degreesToRadians) }
  52. 52. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } init(degrees: Real) { let degreesToRadians = 1 / Self.radiansToDegrees self.init(radians: degrees * degreesToRadians) }
  53. 53. (2) init(degrees: Real) { self.init(radians: degrees * Self.radiansToDegrees) } init(degrees: Real) { let degreesToRadians = 1 / Self.radiansToDegrees self.init(radians: degrees * degreesToRadians) }
  54. 54. var degrees: Real { set(newDegrees) { let degreesToRadians = 1 / Self.radiansToDegrees radians = newDegrees * degreesToRadians } } (3)
  55. 55. var degrees: Real { set(newDegrees) { let degreesToRadians = 1 / Self.radiansToDegrees radians = newDegrees * degreesToRadians } } (3)
  56. 56. var degrees: Real { set(newDegrees) { let degreesToRadians = 1 / Self.radiansToDegrees radians = newDegrees * degreesToRadians } } (3)
  57. 57. To 🐶 🐕 🐩 😸 🐈 😽
  58. 58. To 🐶 🐕 🐩 😸 🐈 😽 To 🐶 🐕 🐩😸 🐈 😽
  59. 59. protocol AngleProtocol { associatedtype Real: init(radians: Real) var radians: Real { set get } } FloatingPoint
  60. 60. protocol AngleProtocol { associatedtype Real: init(radians: Real) var radians: Real { set get } } FloatingPoint
  61. 61. protocol AngleProtocol { associatedtype Real: init(radians: Real) var radians: Real { set get } } TrigonometricFloatingPoint
  62. 62. protocol AngleProtocol { associatedtype Real: init(radians: Real) var radians: Real { set get } } TrigonometricFloatingPoint protocol TrigonometricFloatingPoint: FloatingPoint { static func sine(radians: Self) -> Self static func cosine(radians: Self) -> Self }
  63. 63. sin
  64. 64. sin func sin(_ angle: AngleProtocol) -> ???? { }
  65. 65. sin func sin(_ angle: AngleProtocol) -> ???? { }
  66. 66. sin func sin<A: AngleProtocol>(_ angle: A) -> A.Real { return A.Real.sine(radians: angle.radians) } func sin(_ angle: AngleProtocol) -> ???? { }
  67. 67. CGAngle struct CGAngle: AngleDegreesConvertible { var radians: CGFloat static var radiansToDegrees: CGFloat { return 180/CGFloat.pi } } 😍
  68. 68. CGAngle struct CGAngle: AngleDegreesConvertible { var radians: CGFloat static var radiansToDegrees: CGFloat { return 180/CGFloat.pi } } 😍
  69. 69. protocol Point2DProtocol { associatedtype Scalar: FloatingPoint init(_ x: Scalar, _ y: Scalar) var x: Scalar { get set } var y: Scalar { get set } }
  70. 70. … static func +(lhs: Self, rhs: Self) -> Self { return Self(lhs.x + rhs.x, lhs.y + rhs.y) } static prefix func -(p: Self) -> Self { return Self(-p.x, -p.y) } static func -(lhs: Self, rhs: Self) -> Self { return lhs+(-rhs) } extension Point2DProtocol { }
  71. 71. … extension Point2DProtocol { } var lengthSquared: Scalar { return self*self } var length: Scalar { return lengthSquared.squareRoot() } func projected(on other: Self) -> Self { return ((self*other)/(other*other))*other } 🤠
  72. 72. extension CGPoint: Point2DProtocol { public init(_ x: CGFloat, _ y: CGFloat) { self.x = x self.y = y } } 💯
  73. 73. let newPoint = transform * point [ ]a db c [x y ]=[ax + cy ]bx + dy
  74. 74. let newPoint = transform * point [ ]a db c 1 tx ty 0 0 [x y 1 ]=[ax + cy + tx 1 ]bx + dy + ty
  75. 75. CGAffineTransform
  76. 76. CGAffineTransform Think Different
  77. 77. CGAffineTransform Think Different ][ax + cy + tx 1bx + dy + ty [ ]a d b c 1tx ty 0 0 [x y 1 ]=
  78. 78. let newPoint = transform * point ][ax + cy + tx 1bx + dy + ty [ ]a d b c 1tx ty 0 0 [x y 1 ]=
  79. 79. let newPoint = transform * point ][ax + cy + tx 1bx + dy + ty [ ]a d b c 1tx ty 0 0 [x y 1 ]=
  80. 80. let newPoint = transform * point let newPoint = point * transform ][ax + cy + tx 1bx + dy + ty [ ]a d b c 1tx ty 0 0 [x y 1 ]=
  81. 81. A C (0, 0)
  82. 82. A C (7, 7) xa = (7, 7) (0, 0)
  83. 83. A C (7, 7) yc = xa * aToC xa = (7, 7) (0, 0)
  84. 84. A C (7, 7) (1,0) yc = xa * aToC xa = (7, 7) yc == (1, 0) (0, 0)
  85. 85. A C (7, 7) (1,0) yc = xa * aToC xa = (7, 7) yc == (1, 0) yc * aToC (0, 0)
  86. 86. A C (7, 7) (1,0) yc = xa * aToC xa = (7, 7) yc == (1, 0) yc * aToC (0, 0)
  87. 87. A
  88. 88. A B
  89. 89. A C
  90. 90. A C aToB * bToC
  91. 91. A C aToB * bToC aToC =
  92. 92. [ ]1 10 0 1 0 0 tx ty [ ]sx sy0 0 1 0 0 0 0 [ ] cos a cos a-sin a sin a 1 0 0 0 0 translation scale rotation [ ]1 10 0 1 0 0 0 0 identity [ ]-1 10 0 1 0 0 0 0 horizontal flip [ ]1 -10 0 1 0 0 0 0 vertical flip
  93. 93. ctm [ ]2 -20 0 1 0 0 0 1096 userToDevice
  94. 94. CGAffineTransform extension CGAffineTransform { static func *(point: CGPoint, transform: CGAffineTransform) -> CGPoint { return point.applying(transform) } static func *(lhs: CGAffineTransform, rhs: CGAffineTransform) -> CGAffineTransform { return lhs.concatenating(rhs) } } modelToDevice = modelToUser * userToDevice devicePoint = userPoint * userToDevice
  95. 95. 2 let house: [CGPoint] = [CGPoint(1,-1), CGPoint(1,1), CGPoint(0,2), CGPoint(-1,1), CGPoint(-1,-1)]
  96. 96. 2 let house: [CGPoint] = [CGPoint(1,-1), CGPoint(1,1), CGPoint(0,2), CGPoint(-1,1), CGPoint(-1,-1)] context.saveGState() defer { context.restoreGState() } let userToDevice = context.ctm context.concatenate(userToDevice.inverted())
  97. 97. 2 let modelToUser = CGAffineTransform(scaleX: 1, y: -1) * CGAffineTransform(scaleX: 100, y: 100) * CGAffineTransform(translationX: bounds.width/2, y: bounds.height/2)
  98. 98. 2 let modelToUser = CGAffineTransform(scaleX: 1, y: -1) * CGAffineTransform(scaleX: 100, y: 100) * CGAffineTransform(translationX: bounds.width/2, y: bounds.height/2) let modelToDevice = modelToUser * userToDevice context.concatenate(modelToDevice)
  99. 99. 2 context.move(to: house.first!) house.dropFirst().forEach { context.addLine(to: $0)} context.closePath() context.strokePath()
  100. 100. protocol CoordinateSpace {} enum ModelSpace: CoordinateSpace {} enum UserSpace: CoordinateSpace {} enum DeviceSpace: CoordinateSpace {}
  101. 101. struct CGPointT<Space: CoordinateSpace>: Point2DProtocol { var xy: CGPoint : } let house: [CGPointT<ModelSpace>] = [CGPointT(1,-1), CGPointT(1,1), CGPointT(0,2), CGPointT(-1,1), CGPointT(-1,-1)]
  102. 102. struct CGAffineTransformT<From: CoordinateSpace, To: CoordinateSpace> { var matrix: CGAffineTransform public func inverted() -> CGAffineTransformT<To,From> { return CGAffineTransformT<To,From>(matrix.inverted()) } }
  103. 103. struct CGAffineTransformT<From: CoordinateSpace, To: CoordinateSpace> { var matrix: CGAffineTransform public func inverted() -> CGAffineTransformT<To,From> { return CGAffineTransformT<To,From>(matrix.inverted()) } } public func * <From,To,I>(from: CGAffineTransformT<From, I>, to: CGAffineTransformT<I, To>) -> CGAffineTransformT<From, To> { return CGAffineTransformT<From,To> (from.matrix.concatenating(to.matrix)) }
  104. 104. To 🐶 🐕 🐩 😸 🐈 😽
  105. 105. To 🐶 🐕 🐩 😸 🐈 😽 To 😸 🐈 😽 To 😸 🐈 😽
  106. 106. ARKit 3 SIMD [ ]matrix_float4x4 [ ]float4 post multiply To [ ]float4
  107. 107. ARKit 3 From worldFromCameralet worldPoint = * cameraPoint
  108. 108. float4_t struct float4_t<Space: CoordinateSpace> { var point: float4 init(_ point: float4) { self.point = point } }
  109. 109. matrix_float4x4_t struct matrix_float4x4_t<To: CoordinateSpace, From: CoordinateSpace> { var matrix: matrix_float4x4 init(_ matrix: matrix_float4x4) { self.matrix = matrix } }
  110. 110. extension matrix_float4x4_t { static func *<To, From>(lhs: matrix_float4x4_t<To, From>, rhs: float4_t<From>) -> float4_t<To> { return float4_t<To>(lhs.matrix * rhs.point) } }
  111. 111. transform
  112. 112. transform
  113. 113. transform cameraFromWorld worldFromCamera
  114. 114. transform cameraFromWorld worldFromCamera
  115. 115. final class TypedTransforms<Base> { let base: Base init(_ base: Base) { self.base = base } }
  116. 116. final class TypedTransforms<Base> { let base: Base init(_ base: Base) { self.base = base } } protocol TypedTransformAdditions { associatedtype Typed var typed: Typed { get } }
  117. 117. final class TypedTransforms<Base> { let base: Base init(_ base: Base) { self.base = base } } protocol TypedTransformAdditions { associatedtype Typed var typed: Typed { get } } extension TypedTransformAdditions { var typed: TypedTransforms<Self> { return TypedTransforms(self) } }
  118. 118. extension ARCamera: TypedTransformAdditions {}
  119. 119. extension TypedTransforms where Base: ARCamera { var worldFromCamera: matrix_float4x4_t<WorldSpace, CameraSpace> { return matrix_float4x4_t(base.transform) } } extension ARCamera: TypedTransformAdditions {}
  120. 120. let worldFromCamera = frame.camera.typed.worldFromCamera
  121. 121. let shotDirectionCamera = float4_t<CameraSpace>(float4(0, 0, -3, 1)) let shotDirectionWorld = worldFromCamera * shotDirectionCamera let direction = SCNVector3(float4: shotDirectionWorld.point) let worldFromCamera = frame.camera.typed.worldFromCamera
  122. 122. let position = SCNVector3(float4: worldFromCamera.matrix.columns.3) [ ] matrix_float4x4 tx ty tz 1 0 21 3
  123. 123. let ball = Ball() ball.position = position ball.physicsBody?.applyForce(direction, asImpulse: true) sceneView.scene.rootNode.addChildNode(ball)

×