Implement a reusable protocol MappableRange for handling normalized interpolation (lerp) and range remapping (value -> % -> value).
✅ Goals:
Abstract start, end, and length of any scalar range.
Provide readable methods:
normalizedPosition(for:) (aka inverse lerp)
interpolatedValue(at:) (aka lerp)
remap(_:from:) (range-to-range mapping)
📦 Includes:
Default implementation in protocol extension.
Support for:
Custom struct Distance
Native ClosedRange<T: FloatingPoint>
import Foundation
import CoreGraphics
// MARK: - Протокол
protocol MappableRange {
associatedtype Scalar: BinaryFloatingPoint
var start: Scalar { get }
var end: Scalar { get }
func contains(_ value: Scalar) -> Bool
func length() -> Scalar
func normalizedPosition(for value: Scalar) -> Scalar
func interpolatedValue(at normalizedPosition: Scalar) -> Scalar
func remap(_ value: Scalar, from source: Self) -> Scalar
}
// MARK: - Default Implementation
extension MappableRange {
func contains(_ value: Scalar) -> Bool {
value >= start && value <= end
}
func length() -> Scalar {
end - start
}
func normalizedPosition(for value: Scalar) -> Scalar {
(value - start) / length()
}
func interpolatedValue(at normalizedPosition: Scalar) -> Scalar {
start + normalizedPosition * length()
}
func remap(_ value: Scalar, from source: Self) -> Scalar {
let position = source.normalizedPosition(for: value)
return interpolatedValue(at: position)
}
}
// MARK: - Distance Struct
struct Distance<T: BinaryFloatingPoint>: MappableRange {
var x1: T
var x2: T
var start: T { x1 }
var end: T { x2 }
init(_ x1: T, _ x2: T) {
self.x1 = x1
self.x2 = x2
}
}
// MARK: - ClosedRange поддержка
extension ClosedRange: MappableRange where Bound: BinaryFloatingPoint {
var start: Bound { lowerBound }
var end: Bound { upperBound }
}
Implement a reusable protocol MappableRange for handling normalized interpolation (lerp) and range remapping (value -> % -> value).
✅ Goals:
Abstract start, end, and length of any scalar range.
Provide readable methods:
normalizedPosition(for:) (aka inverse lerp)
interpolatedValue(at:) (aka lerp)
remap(_:from:) (range-to-range mapping)
📦 Includes:
Default implementation in protocol extension.
Support for:
Custom struct Distance
Native ClosedRange<T: FloatingPoint>