我试图弄清楚如何根据UIPanGestureRecognizer
的速度构建有限范围的浮点值。我的最小值或起始值为1.0,最大值为3.0,以便为UIBezierPath
lineWidth
属性提供有限的范围。
我试图弄清楚如何根据UIPanGestureRecognizer
的速度建立一个从1.0到3.0的指数范围,但是我很难开始进行映射价值。组合的x和y速度越快,线宽应该越小(低至1.0),并且如果组合速度越慢则分别相反,高达3.0。我还试图通过存储lastWidth
属性来逐渐缩小/平滑正在进行的线宽,以便子路径之间的转换不明显。
我感谢所提供的任何帮助。
基于答案的工作和最终代码:
@property (nonatomic, assign) CGFloat lastWidth;
if (recognizer.state == UIGestureRecognizerStateChanged)
{
CGPoint velocity = [recognizer velocityInView:self.view];
CGFloat absoluteVelocity = 1000.0 / sqrtf(pow(velocity.x, 2) + pow(velocity.y, 2));
CGFloat clampedVel = MAX(MIN(absoluteVelocity, 3.0), 1.0);
if (clampedVel > self.lastWidth)
{
clampedVel = self.lastWidth + 0.15;
}
else if (clampedVel < self.lastWidth)
{
clampedVel = self.lastWidth - 0.15;
}
self.lastWidth = clampedVel;
UIBezierPath *path = [UIBezierPath bezierPath];
path.lineCapStyle = kCGLineCapRound;
path.lineWidth = self.lastWidth;
}
答案 0 :(得分:1)
所以我使用倒指数函数。
从你的速度V(x,y)开始。你的绝对速度显然是:
sqrt(pow(x, 2) + pow(y, 2));
我们将此值称为&#34; v。&#34;
接下来,我们想要一个介于1和3之间的值,其中1是宽度,其中&#34; v&#34;非常高,3是宽度,其中&#34; v&#34;非常低。
我们可以使用以下指数函数来计算:
- (CGFloat)getExponentialWidthForVeloctity(CGFloat)v {
if (v <= 1 / 3.0)
return 3;
CGFloat inverse = 1 / v;
return 1 + inverse;
}
或者这个功能可以将它平滑一点
- (CGFloat)getExponentialRootWidthForVeloctity(CGFloat)v {
//play with this value to get the feel right
//The higher it is, the faster you'll have to go to get a thinner line
CGFloat rootConstantYouCanAdjust = 2;
if (pow(v, rootConstantYouCanAdjust) <= 1 / 3.0)
return 3;
CGFloat inverse = 1 / pow(v, rootConstantYouCanAdjust);
return 1 + inverse;
}
如果感觉不对,请尝试线性解决方案:
- (CGFloat)getLinearWidthForVelocity(CGFloat)v {
//Find this value by swiping your finger really quickly and seeing what the fastest velocity you can get is
CGFloat myExpectedMaximumVelocity = 1000;
if (v > myExpectedMaximumVelocity)
v = myExpectedMaximumVelocity;
return 3 - 2 * (v / myExpectedMaximumVelocity);
}
最后,作为奖励,尝试这个基于sqrt的功能,你可能会觉得很好用:
- (CGFloat)getSqrtWidthForVelocity(CGFloat)v {
//find the same way as above
CGFloat myExpectedMaximumVelocity = 1000;
if (v > myExpectedMaximumVelocity)
return 1;
return 3 - 2 * sqrt(v) / sqrt(myExpectedMaximumVelocity);
}
我很想知道哪种方法效果最好!让我知道。我有更多的功能,这些只是一些非常简单的功能,应该让你开始。