Skip to content

Instantly share code, notes, and snippets.

@rr-codes
Created July 12, 2020 00:45
Show Gist options
  • Select an option

  • Save rr-codes/0a9b1ff8225690e766030fdd20127498 to your computer and use it in GitHub Desktop.

Select an option

Save rr-codes/0a9b1ff8225690e766030fdd20127498 to your computer and use it in GitHub Desktop.
Currently, the invariant is false for all `percentFilled != 0.5 && angle != 0`. I believe this is because of the x-values of the points
/// A view representing a dynamically moving fluid with a quadrilateral
/// - Invariant: The area of the view is exactly equal to the area of the rectangle of the parent view times `percentFilled`
struct FluidView: Shape {
var angle: CGFloat = 0.0
var percentFilled: CGFloat = 0
var animatableData: CGFloat {
get { angle }
set { self.angle = newValue }
}
/// Creates a new FluidView
/// - Parameters:
/// - angle: A value in the range `0...1`. A value of `0` indicates the view is horizontal, and an angle of `1` indicates the view is vertical (horizontal if viewed as landscape)
/// - percentFilled: the amount of the view bounds to fill represented as a value in the range `0...1`. A value of `x` indicates that `x * 100`% of the parent view is covered by this view
init(angle: CGFloat = 0, percentFilled: CGFloat = 0) {
precondition(0...1 ~= angle)
precondition(0...1 ~= percentFilled)
self.angle = angle
self.percentFilled = percentFilled
}
func path(in rect: CGRect) -> Path {
var path = Path()
path.move(to: CGPoint(x: 0, y: rect.height * (1 - percentFilled))) // top left
let lines = [
CGPoint(x: 0, y: rect.height), // bottom left
CGPoint(x: rect.width, y: rect.height), // bottom right
CGPoint(x: rect.width, y: (rect.height * (1 - percentFilled)) * (1 + angle)), // top right
CGPoint(x: 0, y: (rect.height * (1 - percentFilled)) * (1 - angle)) // top left
].map { pt in
// make sure no points exceed the bounds
CGPoint(x: pt.x, y: min(rect.height, pt.y))
}
// postcondition
check(lines.area == rect.area * percentFilled) {
"actual: \(lines.area), expected: \(rect.area * percentFilled)"
}
path.addLines(lines)
return path
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment