Swiftpack.co - Iliasnolsson/MathEnhancer as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by Iliasnolsson.
Iliasnolsson/MathEnhancer 1.1.1
A Swift Package with additional math functionality & utility
⭐️ 0
🕓 1 year ago
.package(url: "https://github.com/Iliasnolsson/MathEnhancer.git", from: "1.1.1")

MathEnhancer

MathEnhancer is a Swift package that provides extensions to the Swift math library. It includes a range of useful math functions and utility methods that expand upon the functionality of the Swift core library.

Features

  • Interpolation functions for CGFloat and Double.
  • Clamping functions for CGFloat and Double.
  • Trimming and normalizing functions for CGLine.
  • Convenience methods for manipulating CGSize, including addition, subtraction, multiplication, and division.
  • Additional functionality for CGPoint, including distance calculations, colinearity checks, and arithmetic operations.

Installation

To use MathEnhancer in your Swift project, simply add it as a dependency in your Package.swift file:

swift

dependencies: [
    .package(url: "https://github.com/Iliasnolsson/MathEnhancer", from: "1.0.0"..<"2.0.0")
]

After adding the package, you can import it into your Swift file and use it with the standard CGPoint, CGSize, and CGFloat types:

swift

import MathEnhancer

// Using the `+` operator on a `CGPoint`
let pointA = CGPoint(x: 10, y: 20)
let pointB = CGPoint(x: 5, y: 10)
let sum = pointA + pointB // CGPoint(x: 15, y: 30)

// Using the `*` operator on a `CGSize`
let sizeA = CGSize(width: 10, height: 20)
let sizeB = CGSize(width: 2, height: 3)
let product = sizeA * sizeB // CGSize(width: 20, height: 60)

// Using the `-` operator on a `CGFloat`
let floatA: CGFloat = 10.0
let floatB: CGFloat = 5.0
let difference = floatA - floatB // 5.0

Requirements

  • iOS 11.0+ / macOS 10.12+ / tvOS 11.0+ / watchOS 4.0+
  • Xcode 12.0+
  • Swift 5.6+

Usage

MathEnhancer adds the Operable protocol and several extensions to common types, including:

  • Int
  • CGFloat
  • Float
  • Double
  • CGPoint
  • CGSize

MathEnhancer makes it easy to perform mathematical operations on CGPoint, CGSize, and CGFloat types. Here are some examples of how you can use the package to simplify your code:

import MathEnhancer

// Interpolating between two `CGPoint` values
let pointA = CGPoint(x: 10, y: 20)
let pointB = CGPoint(x: 50, y: 100)
let interpolatedPoint = pointA.interpolateTo(pointB, amount: 0.5) // CGPoint(x: 30, y: 60)

// Scaling a `CGSize` to fit inside another `CGSize`
let sizeA = CGSize(width: 100, height: 200)
let sizeB = CGSize(width: 50, height: 50)
let scale = sizeA.scaleThatFits(sizeB) // 0.25

// Adding a `CGFloat` to a `CGSize` or `CGPoint`
let pointA = CGPoint(x: 10, y: 20)
let sizeA = CGSize(width: 50, height: 100)
let addedPoint = pointA +| 5 // CGPoint(x: 10, y: 25)
let addedSize = sizeA +| 10 // CGSize(width: 50, height: 110)

// Subtracting a `CGFloat` from a `CGSize` or `CGPoint`
let pointA = CGPoint(x: 10, y: 20)
let sizeA = CGSize(width: 50, height: 100)
let subtractedPoint = pointA +- 5 // CGPoint(x: 15, y: 20)
let subtractedSize = sizeA *- 0.5 // CGSize(width: 25, height: 50)

In addition to the above examples, MathEnhancer also provides an Operable protocol, which allows you to perform mathematical operations on custom types as well. Here's an example of how you can use Operable to extend

Conforming to Operable

MathEnhancer can be extended to support additional types as well. For example, let's say you have a custom Vector2D struct:

struct Vector2D {
    var x: CGFloat
    var y: CGFloat
}

You can make Vector2D operable by extending it to conform to Operable:

extension Vector2D: Operable {
    static func +(left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x + right.x, y: left.y + right.y)
    }
    
    static func -(left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x - right.x, y: left.y - right.y)
    }
    
    static func *(left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x * right.x, y: left.y * right.y)
    }
    
    static func /(left: Vector2D, right: Vector2D) -> Vector2D {
        return Vector2D(x: left.x / right.x, y: left.y / right.y)
    }
}

You can now use +, -, *, and / on Vector2D objects:

let vectorA = Vector2D(x: 2.0, y: 4.0)
let vectorB = Vector2D(x: 3.0, y: 6.0)
let vectorC = vectorA + vectorB 

Extending Operable

In addition to the standard mathematical operations provided by Operable, you can also extend it to add custom operations. Here's an example of how you can create an extension to add a pow function to Operable, which raises a value to a given power:

public extension Operable {
    
    /// Raises the value to the given power
    static func pow(_ value: Self, power: Int) -> Self {
        var result = value
        for _ in 1..<power {
            result = result * value
        }
        return result
    }
    
}

With this extension, you can now use the pow function on any type that conforms to Operable. Here's an example of how you can use it on both CGFloat and CGPoint:

import MathEnhancer

let floatA: CGFloat = 2.0
let floatB = CGFloat.pow(floatA, power: 3) // 8.0

let pointA = CGPoint(x: 2, y: 3)
let pointB = CGPoint.pow(pointA, power: 2) // CGPoint(x: 4, y: 9)

In the example above, pow is used to raise a CGFloat value to the power of 3, and a CGPoint to the power of 2. Since both types conform to Operable, the pow function can be used on them.

CGPoint Extension

This extension adds useful methods and operator overloads to CGPoint. Most of these extension methods are also available for CGSize

distanceTo(_:)

Returns the distance between the receiver and the given point.

let pointA = CGPoint(x: 1, y: 1)
let pointB = CGPoint(x: 4, y: 5)
let distance = pointA.distanceTo(pointB)
// distance == 5.0

distanceXYTo(_:)

Returns the distance between the receiver and the given point in x and y components.

let pointA = CGPoint(x: 1, y: 1)
let pointB = CGPoint(x: 4, y: 5)
let distance = pointA.distanceXYTo(pointB)
// distance == CGPoint(x: 3, y: 4)

vectorLength

Returns the length between the receiver and CGPoint.zero.

let pointA = CGPoint(x: 3, y: 4)
let length = pointA.vectorLength
// length == 5.0

rounded(decimal:)

Returns a new CGPoint that has its x and y coordinates rounded to the given number of decimal places.

let pointA = CGPoint(x: 3.14159, y: 2.71828)
let roundedPoint = pointA.rounded(decimal: 2)
// roundedPoint == CGPoint(x: 3.14, y: 2.72)

colinear(_:_:)

Returns a Boolean indicating whether the three points are collinear.

let pointA = CGPoint(x: 1, y: 1)
let pointB = CGPoint(x: 2, y: 2)
let pointC = CGPoint(x: 3, y: 3)
let collinear = pointA.colinear(pointB, pointC)
// collinear == true

Additional Functionality

  • Rotation of a point around another point: rotate(around:byDegrees:) and rotate(around:byAngle:)
  • Calculation of the angle between two points and the center of a circle: angle(inCircleWithCenter:center:toPointOnCircle:)
  • Scaling of a point: scale(from:by:) and scale(forReaching:byScalingFrom:)
  • Mathematical operations on points, such as adding or subtracting values from the x or y component: add(x:), add(y:), subtract(x:), subtract(y:), divide(xBy:), divide(yBy:), and multiply(xBy:), multiply(yBy:)

Here are some examples of how these methods can be used:

let point1 = CGPoint(x: 10, y: 10)
let point2 = CGPoint(x: 20, y: 20)

// Calculate the distance between two points
let distance = point1.distanceTo(point2)

// Rotate a point around another point
let center = CGPoint(x: 15, y: 15)
let rotatedPoint = point1.rotate(around: center, byDegrees: 45)

// Scale a point to reach a target point from another point
let target = CGPoint(x: 30, y: 30)
let scaledPoint = point1.scale(forReaching: target, byScalingFrom: center)

// Add or subtract values to/from the x or y component of a point
let point3 = point1.add(x: 5).subtract(y: 2)

// Divide or multiply the x or y component of a point by a value
let point4 = point1.multiply(xBy: 2).divide(yBy: 3)

// Convert a point to a size
let size = CGPoint(x: 100, y: 200).sizeValue

CGRect Utility

  1. area: Returns the total area of the rectangle.
let rect = CGRect(x: 0, y: 0, width: 10, height: 20)
let area = rect.area // area = 200
  1. center: Returns the center point of the rectangle.
var rect = CGRect(x: 0, y: 0, width: 10, height: 20)
let center = rect.center // center = CGPoint(x: 5, y: 10)

// You can also set the center point of the rectangle:
rect.center = CGPoint(x: 20, y: 30)
  1. topLeft, bottomLeft, topRight, bottomRight: Returns the specified point of the rectangle.
let rect = CGRect(x: 0, y: 0, width: 10, height: 20)
let topLeft = rect.topLeft // topLeft = CGPoint(x: 0, y: 0)
let bottomLeft = rect.bottomLeft // bottomLeft = CGPoint(x: 0, y: 20)
let topRight = rect.topRight // topRight = CGPoint(x: 10, y: 0)
let bottomRight = rect.bottomRight // bottomRight = CGPoint(x: 10, y: 20)

// You can also set the specified point of the rectangle:
rect.topLeft = CGPoint(x: 5, y: 5)

CGPoint, CGRect, CGSize Initalization

A set of methods to make initalization of CoreGraphic types easier

  1. init(center:size:): Initializes a new CGRect with a center point and size.
let center = CGPoint(x: 50, y: 50)
let size = CGSize(width: 100, height: 200)
let rect = CGRect(center: center, size: size) // rect = CGRect(x: 0, y: 0, width: 100, height: 200)
  1. init(_ size: CGSize), init(xy: CGFloat): Initializes a new CGPoint with the specified parameters.
let size = CGSize(width: 100, height: 200)
let point = CGPoint(size) // point = CGPoint(x: 100, y: 200)

let xy = CGFloat(50)
let point2 = CGPoint(xy: xy) // point2 = CGPoint(x: 50, y: 50)
  1. init(_ point: CGPoint), init(wh: CGFloat): Initializes a new CGSize with the specified parameters.
let point = CGPoint(x: 100, y: 200)
let size = CGSize(point) // size = CGSize(width: 100, height: 200)

let wh = CGFloat(50)
let size2 = CGSize(wh: wh) // size2 = CGSize(width: 50, height: 50)

Author

MathEnhancer was developed by Ilias Nikolaidis Olsson.

Contributing

If you'd like to contribute to MathEnhancer, feel free to submit a pull request or open an issue. Your contributions are always welcome!

License

MathEnhancer is released under the MIT license. See LICENSE for details.

GitHub

link
Stars: 0
Last commit: 1 year ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

v1.1.1
1 year ago

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics