2

所以我想做的是使用动力学模型制作一个漂亮的滚动条。问题是抑制过冲。我想展示的行为是,当你过冲(超过最大值/最小值)时,它会抑制定位。

我想要的具体行为是这样的:比如说,Maximumum Overshoot 是 50 像素。这是一张表,表示我希望它如何工作。(这是我能想到的最好的呈现方式)。

Displacement      | Position it | Percent 
of position       | Displays @  | Overshot Over
-------------------------------------------------
    25            |    12.5     |   50%
    100           |    25       |   100%
    200           |    37.5     |   200%
    400           |    43.75    |   400%
    ...                ...          ...

Note: Decimals would obviously round down so we can actually display it.

我很确定我可以递归计算(但我不想这样做)。我认为数学关系是相当明显的,虽然我不完全确定如何去做。 我什至可能想错了,所以请考虑忽略我的图表。重要的是用户不能将窗口移动到超过最大超调值(在本例中为 50 像素)。

这是运行定位设置的代码段...

function KineticModel:SetPosition(NewPosition)
    -- Set's the position of the kinetic model. Using this, it'll calculate velocity.


    local CurrentTime = tick()
    local ElapsedTime = CurrentTime - self.TimeStamp
    local LocalVelocity = ((self.Position - self.LastPosition) * 5) / ElapsedTime

    TimeStamp = CurrentTime
    self:SetVelocity((0.2 * self.Velocity) + (0.8 * LocalVelocity)) -- 20% previous velocity maintained, 80% of new velocity used.

    if NewPosition > self.Maximum then
        print("[KineticModel] - Past Max Manual")
        local Displacement = math.abs(NewPosition - self.Maximum)
        -- Dampen position so it can't go over. 

        self.Position = self.Maximum + (Displacement / self.MaxBounce) -- This doesn't work. :(
    elseif NewPosition < self.Minimum
        print("[KineticModel] - Past Min Manual")
        local Displacement = math.abs(NewPosition - self.Minimum)
        -- Same displacement here
    else
        self.Position = NewPosition
    end

    self.LastPosition = self.Position
    self.OnPositionChange(self.Position)
    print("[KineticModel] - Set Velocity @ "..self.Velocity.."; Local Velocity @ "..LocalVelocity)

end

主要问题是试图找到一种数学方法来找到我应该显示它的位移。我将实现这个位移,基本上在每个点设置之前过滤掉位置,所以如果有潜在的问题,请告诉我。

谢谢。:D

编辑:标题、标签

4

1 回答 1

2

这个答案忽略了有关速度和阻尼等的所有动态方面。我将专注于将可能任意大的超调值转换为具有有界最大值的位移值。

一个简单的公式

具有您所要求的属性的一个简单公式如下:让x ≥ 0成为超调并0 ≤ y ≤ 50成为结果位移。然后,您可以使用如下公式将它们关联起来:

y = 50*x/(x + 75)

该分数x/(x+75)将任意接近 1,x但从未达到它,因此您的位移永远不会超过 50。您可以75在公式中调整它以控制它的收敛速度。对于 75,您将获得:

 x    y
 25  12.5
 50  20.0
100  28.6
200  36.4
400  42.1

更大的灵活性

为了更好地控制曲线的形状,您可以使用一个不同的公式,该公式x在分子和分母中都包含多项式。但是,如果您对通过特定点的曲线有非常严格的要求,或者出于其他原因,上述简单方法还不够用,我只会这样做。

匹配速度

简单的公式可能会导致内容移动的方式出现抖动,因为它的速度很可能与非超载文档的速度不匹配。为了匹配速度,您可以使用一个自由度来控制坡度。最简单的方法是使用相同的输入和输出单位,例如像素。然后你的目标是原点的斜率为 1。

y = 50*x(x + 50) = x/(x/50 + 1)

这将给出以下值:

 x    y
 25  16.7
 50  25.0
100  33.3
200  40.0
400  44.4

插图

这是我提到的两个函数的图,以及表中的数据点。不是完全匹配,但应该相当接近。请注意,对于表格的第一行,我不确定要选择哪个列作为x值,因此现在有两个数据点y=12.5

函数图

于 2013-05-10T09:54:16.020 回答