Skip to content

Commit

Permalink
Added distance
Browse files Browse the repository at this point in the history
- Also added `CIVector` default conformance to `DualTwoDimensional`
- Also added `magnitude` to `DualTwoDimensional`s where the `Length`s match and the distance can be determined. This was done for `CIVector` as sugar for its `.distance` between its two points
- Improved description of how `Rectangle`'s `DualTwoDimensional` conformance needs both `Length`s to be the same. Thankfully didn't need to remove the `associatedtype Length`
- Added an "Easy To Adopt" section to the README, inspired by this new `.distance` API
  • Loading branch information
KyNorthstar committed Nov 17, 2023
1 parent e5c0195 commit b7ab155
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 1 deletion.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@ Who knew there was so much to be done with rectangles?



## Easy To Adopt

This library aims to never get in your way. Minimal arbitrary decisions, maximum flexibility.

For example, other frameworks might say that they help you find the distance from any `CGPoint` to another, but doesn't provide that functionality to any other type.
This one doesn't care what types the two are, as long as thier `x` and `y` coordinates use the same type. That means if you want to measure the distance from some `CGPoint` to some custom 2D point-like structure which also uses `CGFlaot`s, this will happily let you do that with no fuss.



## Thoroughly Tested ##

Over 2,000 test assertions prove that this library works as it says it does
Expand Down
5 changes: 4 additions & 1 deletion Sources/RectangleTools/Basic Protocols/Rectangle.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import Foundation
// MARK: - Rectangle

/// A two-dimensional rectangle
public protocol Rectangle: DualTwoDimensional, CartesianMeasurable {
public protocol Rectangle: DualTwoDimensional, CartesianMeasurable
where FirstDimensionPair.Length == SecondDimensionPair.Length,
FirstDimensionPair.Length == Self.Length
{

/// The unit in which the origin and size are defined
associatedtype Length
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//
// CIVector + DualTwoDimensional.swift
//
//
// Created by The Northstar✨ System on 2023-11-16.
//

import CoreImage



extension CIVector: DualTwoDimensional {

public var firstDimensionPair: FirstDimensionPair {
.init(x: x, y: y)
}


public var secondDimensionPair: SecondDimensionPair {
.init(x: z, y: w)
}



public typealias FirstDimensionPair = CGPoint
public typealias SecondDimensionPair = CGPoint
}



public extension DualTwoDimensional where Self: CIVector {

init(firstDimensionPair: FirstDimensionPair,
secondDimensionPair: SecondDimensionPair) {
self.init(x: firstDimensionPair.x,
y: firstDimensionPair.y,
z: secondDimensionPair.x,
w: secondDimensionPair.y)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Foundation

import MultiplicativeArithmetic



public extension DualTwoDimensional
Expand Down Expand Up @@ -179,3 +181,29 @@ public extension DualTwoDimensional
@inlinable
static var one: Self { self.init(firstDimensionPair: .one, secondDimensionPair: .one) }
}



public extension DualTwoDimensional
where FirstDimensionPair.Length == SecondDimensionPair.Length
{
typealias Length = FirstDimensionPair.Length
}



// MARK: - Math!

public extension DualTwoDimensional
where FirstDimensionPair: Point2D,
SecondDimensionPair: Point2D,
FirstDimensionPair.Length == SecondDimensionPair.Length,
Length: MultiplicativeArithmetic,
Length: AdditiveArithmetic,
Length: ExpressibleByIntegerLiteral
{
/// The magnitude of a vector is the distance from its anchor to its farthest indicated location
var magnitude: Length {
firstDimensionPair.distance(to: secondDimensionPair)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

import Foundation

import MultiplicativeArithmetic



public extension Point2D {
Expand All @@ -19,3 +21,24 @@ public extension Point2D {
self.init(x: other.x, y: other.y)
}
}



public extension Point2D
where Length: MultiplicativeArithmetic,
Length: AdditiveArithmetic,
Length: ExpressibleByIntegerLiteral
{
/// Measures the distance from this point to another point
///
/// - Parameter other: The remote point, to which you want to know the distance from this point
/// - Returns: An absolute distance to the other point (always greater than zero, not implying any direction)
func distance<Other: Point2D>(to other: Other) -> Length
where Other.Length == Self.Length
{
sqrt(
(other.x - x).pow(2)
+ (other.y - y).pow(2)
)
}
}
25 changes: 25 additions & 0 deletions Tests/RectangleToolsTests/Point Tests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Point Tests.swift
//
//
// Created by The Northstar✨ System on 2023-10-26.
//

import XCTest
import RectangleTools



final class Point_Tests: XCTestCase {

func testDistance() {
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 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))
}
}

0 comments on commit b7ab155

Please sign in to comment.