Skip to content

Instantly share code, notes, and snippets.

@oboje
Created September 17, 2017 09:21
Show Gist options
  • Save oboje/945ddb22ff0fa1c8132b13fa11599805 to your computer and use it in GitHub Desktop.
Save oboje/945ddb22ff0fa1c8132b13fa11599805 to your computer and use it in GitHub Desktop.
public extension FloatingPoint {
/// Re-maps a number from one range to another.
///
/// - Parameters:
/// - source: The range to interpret the number as being a part of.
/// - destination: The range to map the number to.
/// - clamped: Whether the result should be clamped to the `to` range. Defaults to `false`.
/// - reversed: whether the output mapping should be revserd, such that
/// as the input increases, the output decreases. Defaults to `false`.
/// - Returns: The input number, scaled from the `from` range to the `to` range.
public func scaled(from source: ClosedRange<Self>, to destination: ClosedRange<Self>, clamped: Bool = false, reversed: Bool = false) -> Self {
let destinationStart = reversed ? destination.upperBound : destination.lowerBound
let destinationEnd = reversed ? destination.lowerBound : destination.upperBound
// these are broken up to speed up compile time
let selfMinusLower = self - source.lowerBound
let sourceUpperMinusLower = source.upperBound - source.lowerBound
let destinationUpperMinusLower = destinationEnd - destinationStart
var result = (selfMinusLower / sourceUpperMinusLower) * destinationUpperMinusLower + destinationStart
if clamped {
result = result.clamped(to: destination)
}
return result
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment