Clamping a value is an operation of moving the value to a range of allowed values. It can be achieved by comparing the value with allowed minimum and maximum values.
For example I was deforming SKWarpGeometryGrid from the direction of a point outside the grid and needed to constrain angles between grid points and the contact point. Maximum and minimum allowed angles were related to the angle between the contact point and the grid’s center point.
The solution I propose extends FloatingPoint and BinaryInteger protocols and gives a very readable form to this example problem:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let angleToCenter: CGFloat = .pi / 5 | |
let angleToGridPoint: CGFloat = .pi / 3 | |
// 1.0471975511966 | |
let allowedRange = (angleToCenter - .pi / 8)...(angleToCenter + .pi / 8) | |
let angle = angleToGridPoint.clamped(to: allowedRange) | |
// 1.02101761241668 |
Extending FloatingPoint protocol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension FloatingPoint { | |
func clamped(to range: ClosedRange<Self>) -> Self { | |
return max(min(self, range.upperBound), range.lowerBound) | |
} | |
} | |
let clamped = 5.4.clamped(to: 5.6...6.1) | |
let clamped = 10.5.clamped(to: 5...7) |
Extending BinaryInteger protocol
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
extension BinaryInteger { | |
func clamped(to range: ClosedRange<Self>) -> Self { | |
return max(min(self, range.upperBound), range.lowerBound) | |
} | |
} | |
let clamped = 10.clamped(to: 5...7) |