Skip to content

Commit

Permalink
Merge pull request #52 from RougeWare/develop
Browse files Browse the repository at this point in the history
Sync develop into master
  • Loading branch information
KyLeggiero authored Aug 6, 2020
2 parents d601b68 + 8e0abf8 commit 428ced0
Show file tree
Hide file tree
Showing 4 changed files with 202 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ public extension Rectangle



// MARK: -
// MARK: - Repositioning

public extension Rectangle where Self.Length: ExpressibleByIntegerLiteral {

Expand Down Expand Up @@ -380,3 +380,84 @@ public extension Rectangle
y: self.minY)
}
}



// MARK: - Combination

public extension Rectangle
where Length: Comparable,
Length: AdditiveArithmetic
{
/// Returns the smallest rectangle which encompasses both this and the given one
///
/// ```
/// │ │ │
/// │ │ ┌────┐ │ ┏━━━━━━━━┯━━━━┓
/// │ │ │ │ │ ┃ ┃
/// │ .union(with: │ └────┘ ) == │ ┃ └ ─ ─┨
/// │ ┌──────┐ │ │ ┠─ ─ ─ ┐ ┃
/// │ └──────┘ │ │ ┗━━━━━━┷━━━━━━┛
/// │ │ │
/// ┼───────────────── ┼───────────────── ┼─────────────────
/// ```
///
/// - Parameter other: The other rectangle which will be encompassed in the result
func union(with other: Self) -> Self {
return Self.init(
minX: min(self.minX, other.minX),
minY: min(self.minY, other.minY),
maxX: max(self.maxX, other.maxX),
maxY: max(self.maxY, other.maxY)
)
}
}



public extension MutableRectangle
where Length: Comparable,
Length: AdditiveArithmetic
{
/// Converts this rectangle into the smallest rectangle which encompasses both this and the given one
///
/// ```
/// │ │ │
/// │ │ ┌────┐ │ ┏━━━━━━━━┯━━━━┓
/// │ │ │ │ │ ┃ ┃
/// │ .formUnion(with: │ └────┘ ) -> │ ┃ └ ─ ─┨
/// │ ┌──────┐ │ │ ┠─ ─ ─ ┐ ┃
/// │ └──────┘ │ │ ┗━━━━━━┷━━━━━━┛
/// │ │ │
/// ┼───────────────── ┼───────────────── ┼─────────────────
/// ```
///
/// - Parameter other: The other rectangle which will be encompassed in the result
mutating func formUnion(with other: Self) {
let template = self.union(with: other)
self.origin = template.origin
self.size = template.size
}
}



public extension Collection
where Element: Rectangle,
Element.Length: Comparable,
Element.Length: AdditiveArithmetic
{
/// Returns the smallest rectangle which encompasses all rectangles in a collection
///
/// See also: `Rectangle.union(with:)`
func grandUnion() -> Element? {
guard let first = self.first else {
return nil
}

return dropFirst()
.reduce(into: first) { grandUnion, rectangle in
grandUnion = grandUnion.union(with: rectangle)
}
}
}
1 change: 1 addition & 0 deletions Tests/LinuxMain.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ tests += SizePositionTests.allTests
tests += TwoDimensionalMeasurementTests.allTests
tests += FourSidedTests.allTests
tests += Rectangle_Edgewise_Init_Tests.allTests
tests += Rectangle_Combination_Tests.allTests
XCTMain(tests)
118 changes: 118 additions & 0 deletions Tests/RectangleToolsTests/Rectangle Combination Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
//
// Rectangle Combination Tests.swift
// RectangleTools
//
// Created by Ben Leggiero on 2020-08-05.
// Copyright © 2019 Ben Leggiero BH-1-PS.
//

import XCTest
import RectangleTools



final class Rectangle_Combination_Tests: XCTestCase {

/// ```
/// ↑
/// │
/// 6│
/// 5│
/// 4│
/// 3│ ┏━━━━━━━━┓
/// 2│ ┗━━━━━━━━┛
/// 1│
/// ←┼──────────────────→
/// ↓ 1 2 3 4 5 6
/// ```
let rect__1_2__3_1 = DecimalRectangle(x: 1, y: 2, width: 3, height: 1)

/// ```
/// ↑
/// │
/// 6│ ┏━━━━━┓
/// 5│ ┃ ┃
/// 4│ ┗━━━━━┛
/// 3│
/// 2│
/// 1│
/// ←┼──────────────────→
/// ↓ 1 2 3 4 5 6
/// ```
let rect__4_4__2_2 = DecimalRectangle(x: 4, y: 4, width: 2, height: 2)

/// ```
/// ↑
/// │
/// 6│
/// 5│ ┏━━┓
/// 4│ ┃ ┃
/// 3│ ┗━━┛
/// 2│
/// 1│
/// ←┼──────────────────→
/// ↓ 1 2 3 4 5 6
/// ```
let rect__2_3__2_2 = DecimalRectangle(x: 2, y: 3, width: 2, height: 2)


func test_union_with() {
let union = rect__1_2__3_1.union(with: rect__4_4__2_2)

XCTAssertEqual(union.origin.x, 1)
XCTAssertEqual(union.origin.y, 2)
XCTAssertEqual(union.size.width, 5)
XCTAssertEqual(union.size.height, 4)

let union2 = union.union(with: rect__2_3__2_2)

XCTAssertEqual(union2.origin.x, 1)
XCTAssertEqual(union2.origin.y, 2)
XCTAssertEqual(union2.size.width, 5)
XCTAssertEqual(union2.size.height, 4)
}


func test_formUnion_with() {
var union = rect__1_2__3_1
union.formUnion(with: rect__4_4__2_2)

XCTAssertEqual(union.origin.x, 1)
XCTAssertEqual(union.origin.y, 2)
XCTAssertEqual(union.size.width, 5)
XCTAssertEqual(union.size.height, 4)

union.formUnion(with: rect__2_3__2_2)

XCTAssertEqual(union.origin.x, 1)
XCTAssertEqual(union.origin.y, 2)
XCTAssertEqual(union.size.width, 5)
XCTAssertEqual(union.size.height, 4)
}


func test_grandUnion() {
for _ in (1...5) {
let grandUnion = [
rect__1_2__3_1,
rect__2_3__2_2,
rect__4_4__2_2,
]
.shuffled()
.grandUnion()
?? .init(origin: .zero, size: .zero)

XCTAssertEqual(grandUnion.origin.x, 1)
XCTAssertEqual(grandUnion.origin.y, 2)
XCTAssertEqual(grandUnion.size.width, 5)
XCTAssertEqual(grandUnion.size.height, 4)
}
}


static let allTests = [
("test_union_with", test_union_with),
("test_formUnion_with", test_formUnion_with),
("test_grandUnion", test_grandUnion),
]
}
1 change: 1 addition & 0 deletions Tests/RectangleToolsTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public func allTests() -> [XCTestCaseEntry] {
testCase(TwoDimensionalMeasurementTests.allTests),
testCase(FourSidedTests.allTests),
testCase(Rectangle_Edgewise_Init_Tests.allTests),
testCase(Rectangle_Combination_Tests.allTests),
]
}
#endif

0 comments on commit 428ced0

Please sign in to comment.