我试图通过手动更改窗体的不透明度来为我的窗体添加淡入淡出效果,但是我在计算正确值以通过窗体的不透明度值增加时遇到一些麻烦。
我知道我可以使用AnimateWindow API,但它显示了一些意想不到的行为,我宁愿手动操作,以避免任何p / invoke,所以我可以稍后在Mono中使用它。
我的应用程序支持从1到10的速度。我手动计算速度为1(最慢)我应该增加不透明度0.005和速度10(最快)我应该增加0.1。至于1到10之间的速度,我使用以下表达式来计算正确的值:
double opSpeed = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1; // X = [1, 10]
我虽然这可以给我一个线性值,那就没关系。但是,对于等于4及以上的X,它已经太快了。比它应该更多。我的意思是,速度在7和10之间,我几乎看不出差异,这些值的动画速度应该稍微间隔一点
请注意,我仍然希望最快增量为0.1,最慢增量为0.005。但我需要所有其他人在他们之间保持线性关系。
我做错了什么?
它实际上是有道理的,例如,对于增量之间的固定间隔,比如几毫秒,并且使用上面的等式,如果X = 10,则opSpeed = 0.1并且如果X = 5,则opSpeed = 0.47 。如果我们考虑这个,值为0.1将循环10次,值为0.47将循环为双倍。对于只有几毫秒的这么小的间隔,这些值之间的差异并不大到将速度从5分到10分。
我想你想要的是:
0.005 + ((0.1-0.005)/9)*(X-1)
X的范围从1-10
当X = 1时,这给出对应于0.005的线性标度,当X = 10时给出对应于0.1的线性标度
在下面的评论之后,我还包括我的答案适合几何系列而不是线性比例。
0.005 * (20^((X-1)/9)))
当X = 1时,产生对应于0.005的几何变化,当X = 10时,得到0.1
经过更多讨论后,如下面的评论所示,更新如下。
@Nazgulled在我的几何系列和他实际需要的手动值之间找到了以下关系,以确保平滑的淡入淡出动画。
这意味着几何/指数系列是要走的路。
经过几个小时的努力,想出适当的曲线拟合右侧图并得到一个合适的方程式,@ Nazgulled告诉我,Wolfram | Alpha就是这么做的。真是太神奇了。 :)
他应该拥有他现在想要的东西,除非上面的等式有很高的误差。
你的问题源于人眼的反应不是线性的;准确地说,眼睛没有记录0.05到0.10之间的亮度与0.80和0.85之间的亮度差异相同。整个主题很复杂;您可能想要搜索短语“伽马校正”以获取一些其他信息。一般来说,您可能希望找到一个有效“伽马校正”人类眼睛反应的方程式,并将其用作您的衰落函数。
这不是一个真正的答案,但我只想指出,到目前为止发布的所有人,包括原始问题,都发布了相同的等式。所以有了四个独立的推导,也许我们应该假设这个方程可能是正确的。
我做了代数,但这里是验证的代码(在Python中,顺便说一句,添加了偏移以分隔曲线:
from pylab import *
X = arange(1, 10, .1)
opSpeed0 = (((0.1 - 0.005) * (10 - X)) / (1 - 10)) + 0.1 # original
opSpeed1 = 0.005 + ((0.1-0.005)/9)*(X-1) # Suvesh
opSpeed2 = 0.005*((10-X)/9.) + 0.1*(X-1)/9. # duffymo
a = (0.1 - 0.005) / 9 #= 0.010555555555... # Roger
b = 0.005 - a #= -0.00555555555...
opSpeed3 = a*X+b
nonlinear01 = 0.005*2**((2*(-1 + X))/9.)*5**((-1 + X)/9.)
plot(X, opSpeed0)
plot(X, opSpeed1+.001)
plot(X, opSpeed2+.002)
plot(X, opSpeed3+.003)
plot(X, nonlinear01)
show()
另外,在Nazgulled的要求下,我已经包含了Suvesh提出的非线性曲线(也就是说,顺便说一句,看起来很像伽马校正曲线,正如McWafflestix所建议的那样)。 Suvesh的非线性方程在代码中为nonlinear01
。
这是我如何编程线性关系。但首先我要说清楚我认为你在做什么。
您希望不透明度的变化率是速度的线性函数:
o(v)= o1 * N1(v)+ o2 * N2(v)使得0 <= v <= 1且o(v1)= o1且o(v2)= o2。
如果我们选择N1(v)等于1-v和N2(v)= v,我们最终得到你想要的:
o(c)= o1 *(1-c)+ o2 * c
所以,插入你的价值观:
c =(y-1)/(10-1)=(y-1)/ i
o1 = 0.005,o2 = 0.1
所以函数应该如下所示:
您可以简化这一过程,直到得到o(u)的简单公式,其中1 <= u <= 10.应该可以正常工作。
如果我理解你所追求的是什么,你需要通过平面中这两个点的线的方程:(1,0.005)和(10,0.1)。这种线的一般方程(只要它不是垂直的)是y = ax + b。将两个点插入此等式并求解得到的两个线性方程组
a = (0.1 - 0.005) / 9 = 0.010555555555...
b = 0.005 - a = -0.00555555555...
然后,对于每个整数x = 1,2,3,...,10,将x插入y = ax + b以计算y,即所需的值。