Skip to content

Commit

Permalink
Made (min/max)X(min/max)Y more useful
Browse files Browse the repository at this point in the history
TIL that I can't just `minXminY` on a `CGSize` without specifying I want a `CGPoint` 🤡

Fixing that to make this more ergonomic
  • Loading branch information
KyLeggiero committed Nov 25, 2023
1 parent 79c4161 commit 4799ab4
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,25 @@ public extension Point2D {



public extension Point2D
where Length: BinaryFloatingPoint
{
/// Creates a new point with the given values from a different type
///
/// - Parameters:
/// - x: The X coordinate to convert
/// - y: The Y coordinate to convert
@inline(__always)
init<OtherLength>(x: OtherLength, y: OtherLength)
where OtherLength: BinaryFloatingPoint
{
self.init(measurementX: x,
measurementY: y)
}
}



public extension Point2D
where Length: MultiplicativeArithmetic,
Length: AdditiveArithmetic,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,25 @@ public extension Size2D {



public extension Point2D
where Length: BinaryFloatingPoint
{
/// Creates a new size with the given values from a different type
///
/// - Parameters:
/// - width: The width measurement to convert
/// - height: The height measurement to convert
@inline(__always)
init<OtherLength>(width: OtherLength, height: OtherLength)
where OtherLength: BinaryFloatingPoint
{
self.init(measurementX: width,
measurementY: height)
}
}



// MARK: - CartesianMeasurable

public extension Size2D
Expand Down Expand Up @@ -50,7 +69,7 @@ public extension Size2D
var maxY: Length { max(.zero, height) }


// MARK: Points
// MARK: Generic Point extremities

/// The point with the smallest X and Y values in this size
@inlinable
Expand All @@ -67,7 +86,30 @@ public extension Size2D
/// The point with the largest X and Y values in this size
@inlinable
func maxXmaxY<Point: Point2D>() -> Point where Point.Length == Self.Length { Point.init(x: maxX, y: maxY) }
}



public extension Size2D
where Length: BinaryFloatingPoint
{
// MARK: CGPoint extremities

/// The point with the smallest X and Y values in this size
@inlinable
func minXminY() -> CGPoint { .init(measurementX: minX, measurementY: minY) }

/// The point with the smallest X and largest Y values in this size
@inlinable
func minXmaxY() -> CGPoint { .init(measurementX: minX, measurementY: maxY) }

/// The point with the largest X and smallest Y values in this size
@inlinable
func maxXminY() -> CGPoint { .init(measurementX: maxX, measurementY: minY) }

/// The point with the largest X and Y values in this size
@inlinable
func maxXmaxY() -> CGPoint { .init(measurementX: maxX, measurementY: maxY) }
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,18 @@ import MultiplicativeArithmetic

public extension TwoDimensional where Length: BinaryFloatingPoint {

/// Creates a new 2D with the given values from a different type
///
/// - Parameters:
/// - measurementX: The X measurement to convert
/// - measurementY: The Y measurement to convert
init<OtherLength>(measurementX: OtherLength, measurementY: OtherLength)
where OtherLength: BinaryFloatingPoint
{
self.init(measurementX: .init(measurementX),
measurementY: .init(measurementY))
}

/// Creates a new 2D object by converting the values of the given one
///
/// - Parameter other: Another 2D object to convert
Expand Down
47 changes: 46 additions & 1 deletion Tests/RectangleToolsTests/Point Tests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,57 @@ import RectangleTools

final class Point_Tests: XCTestCase {

func testDistance() {
func testPointToPointDistance() {
XCTAssertEqual(CGPoint(x: 0, y: 0).distance(to: CGPoint(x: 1, y: 1)), sqrt(2))
XCTAssertEqual(CGPoint(x: 0, y: 0).distance(to: CGPoint(x: -1, y: 1)), sqrt(2))
XCTAssertEqual(CGPoint(x: 0, y: 0).distance(to: CGPoint(x: 1, y: -1)), sqrt(2))
XCTAssertEqual(CGPoint(x: 0, y: 0).distance(to: CGPoint(x: -1, y: -1)), sqrt(2))
}


func testSizeExtremitiesDistance() {
var cgSize = CGSize(width: 1, height: 1)
XCTAssertEqual(cgSize.minXminY().distance(to: cgSize.maxXmaxY()), sqrt(2))

cgSize = CGSize(width: -1, height: 1)
XCTAssertEqual(cgSize.minXminY().distance(to: cgSize.maxXmaxY()), sqrt(2))

cgSize = CGSize(width: 1, height: -1)
XCTAssertEqual(cgSize.minXminY().distance(to: cgSize.maxXmaxY()), sqrt(2))

cgSize = CGSize(width: -1, height: -1)
XCTAssertEqual(cgSize.minXminY().distance(to: cgSize.maxXmaxY()), sqrt(2))
}


func testRectExtremitiesDistance() {
var cgRect = CGRect(x: 0, y: 0, width: 1, height: 1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: 0, y: 0, width: -1, height: 1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: 0, y: 0, width: 1, height: -1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: 0, y: 0, width: -1, height: -1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))


cgRect = CGRect(x: .random(in: -1000 ... 1000), y: .random(in: -1000 ... 1000), width: 1, height: 1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: .random(in: -1000 ... 1000), y: .random(in: -1000 ... 1000), width: -1, height: 1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: .random(in: -1000 ... 1000), y: .random(in: -1000 ... 1000), width: 1, height: -1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))

cgRect = CGRect(x: .random(in: -1000 ... 1000), y: .random(in: -1000 ... 1000), width: -1, height: -1)
XCTAssertEqual(cgRect.minXminY.distance(to: cgRect.maxXmaxY), sqrt(2))
}


func testMagnitude() {
// https://www.wolframalpha.com/input?i=distance+from+%28-2%2C-1%29+to+%285%2C6%29
XCTAssertEqual(CIVector(x: -2, y: -1, z: 5, w: 6).magnitude, 7 * sqrt(2))
Expand Down

0 comments on commit 4799ab4

Please sign in to comment.