I want to rotate a needle when user input weight.
The low value and high value is dynamically changed by user's height.
pointer.transform = CGAffineTransform(rotationAngle: CGFloat(weight / low * .pi / 3))
This code is working at under low side. But I don't know how to point low ~ high , over high
CodePudding user response:
What you want to do is to convert weight to a value between 0 and 1 to get a "progress" value. You can do this by using an inverseLerp function, it would look something like this:
let progress = (weight - low) / (high - low)
This formula will return 0 when weight == low and 1 when weight == high.
Now you have to convert that into a rotation. Assuming that the image of your arrow is pointing up by default, we'll need to rotate in a range of [-pi / 2, pi / 2]. pi is half a rotation, so we're doing a quarter of a rotation to the left, and a quarter to the right.
A lerp function turns a value in the range [0, 1], like the one we already have, into a value inside a range, which is just what we need. It looks like this:
let value = (1 - progress) * start progress * end
Using actual values, it would look like this:
let angle = (1 - progress) * (-.pi / 2) progress * (.pi / 2)
We now use that to transform our arrow view:
pointer.transform = CGAffineTransform(rotationAngle: angle)
Views will rotate by the center by default, because this is where their `anchorPoint is located by default. Since we want our view to rotate around the bottom middle of its frame, we can change it like this:
pointer.layer.anchorPoint = CGPoint(0.5, 1)
This should rotate our view like we want it to.
PS: I made a library called CGMath that includes functions like this. You can check it out here.
