Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added distance #67

Merged
merged 2 commits into from
Nov 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 45 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,53 @@

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.
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 Cartesian types
- conveniences for measuring and placing rectangles/points/sizes
- and much more...

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 don'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 `CGFloat`s, this will happily let you do that with no fuss.


For example, let's say you made this for your specific requirements:

```swift
struct AnnotatedPoint {
var x: CGFloat
var y: CGFloat
var annotation: String
}
```

You can quickly and easily find the distance between that and a `CGPoint` like this:

```swift
import RectangleTools

extension AnnotatedPoint: Point2D {
// Nothing to do! 🦆
}
```
```swift
func isCloseEnoughToSnap(cursorPosition: AnnotatedPoint, to anchor: CGPoint) -> Bool {
cursorPosition.distance(to: anchor) < snapDistnce
}
```


## Thoroughly Tested ##

Over 2,000 test assertions prove that this library works as it says it does
Expand All @@ -23,3 +64,6 @@ This library was created for enterprise-scale applications, and is being used by
## SwiftUI ##

If you're using this with SwiftUI, you can also `import RectangleTools_SwiftUI` to gain SwiftUI-specific rectangle tools!



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))
}
}