Skip to content

Commit

Permalink
update materials
Browse files Browse the repository at this point in the history
  • Loading branch information
eugenebokhan committed Jun 17, 2024
1 parent 71e2113 commit b2e2220
Show file tree
Hide file tree
Showing 20 changed files with 451 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,4 @@ fastlane/test_output

iOSInjectionProject/
*.DS_Store
*.swiftpm
70 changes: 70 additions & 0 deletions Sources/SIMDTools/Angle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,19 @@ public struct Angle {
}

/// Creates an instance using the value in radians
/// - Parameter radians: The angle value in radians
public init(radians val: Float32) {
degrees = val / Float32.pi * 180.0
}

/// Creates an instance using the value in degrees
/// - Parameter degrees: The angle value in degrees
public init(degrees val: Float32) {
degrees = val
}

/// Creates an instance using an internal value
/// - Parameter val: The angle value
internal init(_ val: Float32) {
degrees = val
}
Expand Down Expand Up @@ -66,56 +70,105 @@ extension Angle {

// MARK: multiplication (scaling)

/// Multiplies the angle by a scalar value
/// - Parameters:
/// - lhs: The angle to be multiplied
/// - rhs: The scalar value
public static func *=(lhs: inout Angle, rhs: Float32) {
lhs = Angle(lhs.degrees * rhs)
}

/// Multiplies the angle by a scalar value
/// - Parameters:
/// - lhs: The angle to be multiplied
/// - rhs: The scalar value
/// - Returns: The resulting angle after multiplication
public static func *(lhs: Angle, rhs: Float32) -> Angle {
return Angle(lhs.degrees * rhs)
}

/// Multiplies a scalar value by an angle
/// - Parameters:
/// - lhs: The scalar value
/// - rhs: The angle to be multiplied
/// - Returns: The resulting angle after multiplication
public static func *(lhs: Float32, rhs: Angle) -> Angle {
return Angle(rhs.degrees * lhs)
}

// MARK: division (scaling)

/// Divides the angle by a scalar value
/// - Parameters:
/// - lhs: The angle to be divided
/// - rhs: The scalar value
public static func /=(lhs: inout Angle, rhs: Float32) {
lhs = Angle(lhs.degrees / rhs)
}

/// Divides the angle by a scalar value
/// - Parameters:
/// - lhs: The angle to be divided
/// - rhs: The scalar value
/// - Returns: The resulting angle after division
public static func /(lhs: Angle, rhs: Float32) -> Angle {
return Angle(lhs.degrees / rhs)
}

// MARK: addition

/// Adds two angles together
/// - Parameters:
/// - lhs: The first angle
/// - rhs: The second angle
public static func +=(lhs: inout Angle, rhs: Angle) {
lhs = Angle(lhs.degrees + rhs.degrees)
}

/// Adds two angles together
/// - Parameters:
/// - lhs: The first angle
/// - rhs: The second angle
/// - Returns: The resulting angle after addition
public static func +(lhs: Angle, rhs: Angle) -> Angle {
return Angle(lhs.degrees + rhs.degrees)
}

// MARK: subtraction

/// Subtracts one angle from another
/// - Parameters:
/// - lhs: The first angle
/// - rhs: The second angle
public static func -=(lhs: inout Angle, rhs: Angle) {
lhs = Angle(lhs.degrees - rhs.degrees)
}

/// Subtracts one angle from another
/// - Parameters:
/// - lhs: The first angle
/// - rhs: The second angle
/// - Returns: The resulting angle after subtraction
public static func -(lhs: Angle, rhs: Angle) -> Angle {
return Angle(lhs.degrees - rhs.degrees)
}

// MARK: Modulus

/// Returns the remainder of one angle divided by another
/// - Parameters:
/// - lhs: The first angle
/// - rhs: The second angle
/// - Returns: The remainder angle after division
public static func %(lhs: Angle, rhs: Angle) -> Angle {
return Angle(lhs.degrees.truncatingRemainder(dividingBy: rhs.degrees))
}

// MARK: Unary

/// Returns the negation of the angle
/// - Parameter lhs: The angle to be negated
/// - Returns: The negated angle
public static prefix func -(lhs: Angle) -> Angle {
return Angle(-lhs.degrees)
}
Expand Down Expand Up @@ -149,10 +202,18 @@ extension Angle: Comparable {
}
}

/// Computes the sine and cosine of the given angle
/// - Parameters:
/// - a: The angle
/// - sina: A reference to a variable to store the sine of the angle
/// - cosa: A reference to a variable to store the cosine of the angle
public func sincos(_ a: Angle, _ sina: inout Float, _ cosa: inout Float) {
__sincospif(a.degrees / 180.0, &sina, &cosa)
}

/// Computes the sine and cosine of the given angle
/// - Parameter a: The angle
/// - Returns: A tuple containing the sine and cosine of the angle
public func sincos(_ a: Angle) -> (sin: Float, cos: Float) {
var s: Float = 0.0
var c: Float = 0.0
Expand All @@ -161,14 +222,23 @@ public func sincos(_ a: Angle) -> (sin: Float, cos: Float) {
return (sin: s, cos: c)
}

/// Computes the sine of the given angle
/// - Parameter a: The angle
/// - Returns: The sine of the angle
public func sin(_ a: Angle) -> Float {
return __sinpif(a.degrees / 180.0)
}

/// Computes the cosine of the given angle
/// - Parameter a: The angle
/// - Returns: The cosine of the angle
public func cos(_ a: Angle) -> Float {
return __cospif(a.degrees / 180.0)
}

/// Computes the tangent of the given angle
/// - Parameter a: The angle
/// - Returns: The tangent of the angle
public func tan(_ a: Angle) -> Float {
return __tanpif(a.degrees / 180.0)
}
30 changes: 16 additions & 14 deletions Sources/SIMDTools/Helpers.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
/// Returns x, such that min ≤ x ≤ max
///
/// - parameter x: value to be clamped
/// - parameter min: minimum
/// - parameter max: maximum
/// Clamps a value to the specified range
/// - Parameters:
/// - x: The value to be clamped
/// - min: The minimum value
/// - max: The maximum value
/// - Returns: The clamped value
public func clamp<T>(_ x: T, min _min: T, max _max: T) -> T where T: Comparable {
return min(max(x, _min), _max)
}

/// Returns x, where 0.0 ≤ x ≤ 1.0
/// Clamps a value to the range [0.0, 1.0]
/// - Parameter x: The value to be clamped
/// - Returns: The clamped value
public func saturate<T>(_ x: T) -> T where T: BinaryFloatingPoint {
return clamp(x, min: 0.0, max: 1.0)
}

/// Performs a linear interpolation between a and b by the interpolant t
///
/// - parameter a: start value
/// - parameter b: end value
/// - parameter t: interpolant
///
/// - returns: a value interpolated from a to b
public func interpolate<T>(a: T, b: T, t: T) -> T where T: BinaryFloatingPoint {
/// Performs a linear interpolation between two values
/// - Parameters:
/// - a: The start value
/// - b: The end value
/// - t: The interpolant
/// - Returns: A value interpolated from a to b
public func interpolate<T>(a: T, b: T, t: T) -> T where T: BinaryFloatingPoint {
return a + (b - a) * t
}
30 changes: 30 additions & 0 deletions Sources/SIMDTools/SIMDTools.docc/HelperFunctions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Helper Functions

## Clamping Values

Clamp a value to a specified range:

```swift
let clampedValue = clamp(5, min: 1, max: 10) // 5
let clampedValue2 = clamp(15, min: 1, max: 10) // 10
```

## Saturating Values

Saturate a value to the range [0.0, 1.0]:

```swift
let saturatedValue = saturate(1.5) // 1.0
let saturatedValue2 = saturate(-0.5) // 0.0
```

## Linear Interpolation

Perform a linear interpolation between two values:

```swift
let start: Float = 0.0
let end: Float = 10.0
let t: Float = 0.5
let interpolatedValue = interpolate(a: start, b: end, t: t) // 5.0
```
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 10 additions & 5 deletions Sources/SIMDTools/SIMDTools.docc/SIMDTools.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# ``SIMDTools``

Welcome to the documentation for the `simd-tools` Swift package. This package provides utility functions and extensions for working with SIMD matrices and vectors in Swift.
![SIMDTools](simd-tools.png)

Welcome to the documentation for the `SIMDTools` Swift package. This package provides utility functions and extensions for working with SIMD matrices and vectors in Swift.

## Overview

Expand All @@ -11,11 +13,14 @@ The `simd-tools` package includes:

## Topics

### Getting Started
### Essentials

- <doc:UsingAngle>
- <doc:/tutorials/SIMDTools>

### Reference
### Usage

- ``Angle``
- <doc:WorkingWithAngles>
- <doc:WorkingWith3x3Matrices>
- <doc:WorkingWith4x4Matrices>
- <doc:HelperFunctions>

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@Tutorial(time: 30) {
@Intro(title: "Rotating images in SwiftUI") {
This tutorial guides you through building a simple SwiftUI demo app that will demostrate you how to use SwiftUI layer effects to apply affine transform to images. You'll start by building the content view.
@Intro(title: "Applying Affine Transforms To SwiftUI Views With Metal") {
This tutorial guides you through building a simple SwiftUI demo app that will demostrate you how to use SwiftUI layer effects to apply affine transform to a view. You'll start by building the content view.

@Image(source: creating-intro.png, alt: "")
}
Expand Down Expand Up @@ -197,37 +197,51 @@
@Step {
Now its time to create the transform that will rotate the image. Let's start with adding a dedicated function.

@Code(name: "ContentView.swift", file: 01-creating-code-04-01.swift)
@Code(name: "ContentView.swift", file: 01-creating-code-04-01.swift) {
@Image(source: preview-01-creating-code-02-08.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}

@Step {
Create the `angle` variable of `Angle` type from `SIMDTools`.

@Code(name: "ContentView.swift", file: 01-creating-code-04-02.swift)
@Code(name: "ContentView.swift", file: 01-creating-code-04-02.swift) {
@Image(source: preview-01-creating-code-02-08.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}

@Step {
Calculate an offset that will be used in the pre- post-transforms.

@Code(name: "ContentView.swift", file: 01-creating-code-04-03.swift)
@Code(name: "ContentView.swift", file: 01-creating-code-04-03.swift) {
@Image(source: preview-01-creating-code-02-08.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}

@Step {
Create the transform by multiplying pre-, rotation and post-transform using convenience functions from `SIMDTools`.

@Code(name: "ContentView.swift", file: 01-creating-code-04-04.swift)
The transforms are applied from right to left: `.translate(value: -offset)` is the translation to the center, `.rotate(angle: angle)` is the rotation around the center, `.translate(value: offset)` is the translation back to the original position.

@Code(name: "ContentView.swift", file: 01-creating-code-04-04.swift) {
@Image(source: preview-01-creating-code-02-08.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}

@Step {
Decompose the transform into the array of floats.

@Code(name: "ContentView.swift", file: 01-creating-code-04-05.swift)
@Code(name: "ContentView.swift", file: 01-creating-code-04-05.swift) {
@Image(source: preview-01-creating-code-02-08.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}

@Step {
Apply layerEffect to the image.
Apply layerEffect to the image view.

@Code(name: "ContentView.swift", file: 01-creating-code-04-06.swift)
@Code(name: "ContentView.swift", file: 01-creating-code-04-06.swift) {
@Image(source: preview-01-creating-code-04-06.png, alt: "A screenshot from the Xcode preview as it would appear on iPhone, with colored gear image and a rotatio degrees label, centered in the middle of the display.")
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions Sources/SIMDTools/SIMDTools.docc/Tutorials/SIMDTools.tutorial
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
@Tutorials(name: "SIMDTools") {
@Intro(title: "Meet SIMDTools") {
Learn how to use SIMD matrices to calculate affine transform for rotating images. Get started with SIMDTools by buildiong the demo app _RotateImage_.
Learn how to use SIMD matrices to calculate affine transform for rotating SwiftUI views. Get started with SIMDTools by building the demo app _RotateImage_.

@Image(source: simd-tools.png, alt: "SIMDTools icon.")
}

@Chapter(name: "Rotating Image In SwiftUI") {
@Chapter(name: "SIMDTools Essentials") {
@Image(source: chapter1-rotate-image.png, alt: "Rotate Image app main sceen.")

Construct a rotation affine transform using SIMDTools and apply it to rotate an image.

@TutorialReference(tutorial: "doc:RotatingImageInSwiftUI")
@TutorialReference(tutorial: "doc:ApplyingAffineTransformsToSwiftUIViewsWithMetal")
}
}
12 changes: 0 additions & 12 deletions Sources/SIMDTools/SIMDTools.docc/UsingAngle.md

This file was deleted.

Loading

0 comments on commit b2e2220

Please sign in to comment.