Skip to content

Commit

Permalink
Merge pull request #64 from RougeWare/feature/Scaling
Browse files Browse the repository at this point in the history
`Rectangle` & `TwoDimensional` can now be scaled!
  • Loading branch information
KyLeggiero authored Jan 14, 2022
2 parents d91b866 + 7bd8fca commit f168105
Show file tree
Hide file tree
Showing 9 changed files with 1,880 additions and 12 deletions.
8 changes: 2 additions & 6 deletions .github/workflows/swift.yml → .github/workflows/iOS.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Swift
name: iOS

on: [push, pull_request]
on: [pull_request]

jobs:
build:
Expand All @@ -10,10 +10,6 @@ jobs:

steps:
- uses: actions/checkout@v1
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
- name: Generate iOS xcodeproj
run: swift package generate-xcodeproj
- name: Run iOS tests
Expand Down
16 changes: 16 additions & 0 deletions .github/workflows/macOS.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
name: macOS

on: [pull_request]

jobs:
build:

timeout-minutes: 5
runs-on: macOS-latest

steps:
- uses: actions/checkout@v1
- name: Build
run: swift build -v
- name: Run tests
run: swift test -v
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

A set of Swift utilities for dealing with rectangles, including a way to generically build your own!

This package includes new types such as `IntRect` and `UIntPoint`, conveniences for doing math with various points in rectangles, centering and scaling, generic protocols to unify math across all rectangular types, conveniences for measuring and placing rectangles, and much more.

Who knew there was so much to be done with rectangles?



## Thoroughly Tested ##

Over 2,000 test assertions prove that this library works as it says it does



## Battle Hardened ##

This library was created for enterprise-scale applications, and is being used by multiple corporations in production today.



## SwiftUI ##
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,10 @@ public extension TwoDimensional where Length: BinaryFloatingPoint {


/// The ratio of the X dimension to the Y dimension
func aspectRatio() -> CGFloat {
return abs(CGFloat(measurementX) / CGFloat(measurementY))
func aspectRatio() -> CGFloat
where Self.Length: MultiplicativeArithmetic
{
CGFloat(aspectRatioDoingGenericMathWithLengthType())
}
}

Expand All @@ -89,8 +91,8 @@ public extension TwoDimensional where Length: BinaryFloatingPoint {
public extension TwoDimensional where Length == Decimal {

/// The ratio of the X dimension to the Y dimension
func aspectRatio() -> Length {
return abs(measurementX / measurementY)
func aspectRatio() -> Decimal {
abs(measurementX / measurementY)
}
}

Expand Down Expand Up @@ -163,9 +165,44 @@ public extension TwoDimensional where Length: BinaryInteger {


/// The ratio of the X dimension to the Y dimension
func aspectRatio() -> CGFloat {
return abs(CGFloat(measurementX) / CGFloat(measurementY))
func aspectRatio() -> CGFloat
where Length: MultiplicativeArithmetic
{
CGFloat(aspectRatioDoingGenericMathWithLengthType())
}
}



public extension TwoDimensional
where Length: MultiplicativeArithmetic,
Length: AdditiveArithmetic,
Length: Comparable,
Length: ExpressibleByIntegerLiteral {

/// The ratio of the X dimension to the Y dimension. Wider objects result in a greater value. Square objects result in `1`
///
/// This specialization function is necessary because aspect ratios less than 1 cannot be represented by integers
private func aspectRatioDoingGenericMathWithLengthType() -> CGFloat
where Length: BinaryInteger
{
let raw = CGFloat(measurementX) / CGFloat(measurementY)
return raw < 0
? 0 - raw
: raw
}

/// The ratio of the X dimension to the Y dimension. Wider objects result in a greater value. Square objects result in `1`
private func aspectRatioDoingGenericMathWithLengthType() -> Length {
let raw = measurementX / measurementY
return raw < 0
? 0 - raw
: raw
}


/// The ratio of the X dimension to the Y dimension. Wider objects result in a greater value. Square objects result in `1`
func aspectRatio() -> Length { aspectRatioDoingGenericMathWithLengthType() }
}


Expand Down
471 changes: 471 additions & 0 deletions Sources/RectangleTools/Synthesized Conveniences/scaled.swift

Large diffs are not rendered by default.

52 changes: 52 additions & 0 deletions Tests/RectangleToolsTests/Test Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import RectangleTools
// MARK: - Test Sizes

enum TestSizes {

// MARK: Basic test sizes

/// ```
/// ↑
Expand Down Expand Up @@ -190,6 +192,48 @@ enum TestSizes {



// MARK: Sizes for aspect ratio & scaling tests

extension CGSize {

// Wide

/// An extremely wide rectangle (`960×12`)
static let extremelyWide__960_12 = CGSize(width: 960, height: 12)

/// A very wide rectangle (`96×12`)
static let veryWide__96_12 = CGSize(width: 96, height: 12)

/// A somewhat wide rectangle (`18×12`)
static let wide__18_12 = CGSize(width: 18, height: 12)


// Square

/// A small square (`12×12`)
static let squareSmall__12_12 = CGSize(width: 12, height: 12)

/// A medium square (`96×96`)
static let squareMedium__96_96 = CGSize(width: 96, height: 96)

/// A large square (`960×960`)
static let squareLarge__960_960 = CGSize(width: 960, height: 960)


// Tall

/// A somewhat tall rectangle (`12×18`)
static let tall__12_18 = CGSize(width: 12, height: 18)

/// A very tall rectangle (`12×96`)
static let veryTall__12_96 = CGSize(width: 12, height: 96)

/// An extremely tall rectangle (`12×960`)
static let extremelyTall__12_960 = CGSize(width: 12, height: 960)
}



// MARK: - Test Points

enum TestPoints {
Expand Down Expand Up @@ -365,3 +409,11 @@ enum TestPoints {
/// ```
static let decimalPoint__3_n4 = DecimalPoint(x: 3, y: -4)
}



// MARK: - Approximation

extension ExpressibleByFloatLiteral {
static var approximationTolerance: Self { 0.001 }
}
59 changes: 59 additions & 0 deletions Tests/RectangleToolsTests/Testing convenience functions.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
//
// Testing convenience functions.swift
//
//
// Created by Ky Leggiero on 2022-01-11.
//

import Foundation
import RectangleTools



infix operator &&= : AssignmentPrecedence
infix operator ≈≈ : ComparisonPrecedence



/// Shorthand for `lhs = lhs && rhs`
func &&= (lhs: inout Bool, rhs: @autoclosure () -> Bool) {
if lhs, !rhs() {
lhs = false
}
}



/// Whether the left-hand-side argument is approximately equal to the right-hand-side
func ≈≈ <Value> (lhs: Value, rhs: Value) -> Bool
where Value: FloatingPoint,
Value: ExpressibleByFloatLiteral
{
abs(rhs - lhs) < .approximationTolerance
}



/// Whether the left-hand-side argument is approximately equal to the right-hand-side
func ≈≈ <Value> (lhs: Value, rhs: Value) -> Bool
where Value: TwoDimensional,
Value.Length: FloatingPoint,
Value.Length: ExpressibleByFloatLiteral
{
lhs.measurementX ≈≈ rhs.measurementX
&& lhs.measurementY ≈≈ rhs.measurementY
}



/// Whether the left-hand-side argument is approximately equal to the right-hand-side
func ≈≈ <Value> (lhs: Value, rhs: Value) -> Bool
where Value: DualTwoDimensional,
Value.FirstDimensionPair.Length: FloatingPoint,
Value.FirstDimensionPair.Length: ExpressibleByFloatLiteral,
Value.SecondDimensionPair.Length: FloatingPoint,
Value.SecondDimensionPair.Length: ExpressibleByFloatLiteral
{
lhs.firstDimensionPair ≈≈ rhs.firstDimensionPair
&& lhs.secondDimensionPair ≈≈ rhs.secondDimensionPair
}
Loading

0 comments on commit f168105

Please sign in to comment.