2017-12-28 75 views
2

私は次の関数を用いて線形関数にマッピング進歩のためのユーティリティを作成しました:値の間の進捗をS-カーブにマッピングする方法は?

public static func map<T: FloatingPoint>(progress: T, min: T, max: T) -> T { 
    assert(progress >= 0) 
    assert(progress <= 1) 
    return min + ((max - min) * progress) 
} 

これは、あなたが0の最小値を持っている場合は、線形値のセットと100の最大値を返し、次の値は、それぞれの進捗状況のために返されます。

0.1 -> 10 
0.2 -> 20 
0.5 -> 50 
0.8 -> 80 
0.9 -> 90 

私は近いあなたが進歩の開始点と終了点にあるS字曲線に戻り値をマッピングし、同様の機能を作成したいです結果は結果の影響を受けにくくなります。これは、例えば、CADisplayLinkを使ってアニメーションを滑らかにするのに非常に便利です。私は任意のポインタがいただければ幸いです。このためかなり基本的な数式があります確信している

0.1 -> 01 
0.2 -> 10 
0.5 -> 50 
0.8 -> 90 
0.9 -> 99 

:上記の例のために期待される成果は、次のようになります!

答えて

1

あなたが進歩を一つのパラメータの数学的関数として考えることができます。あなたの現在のケースでは、それは線形関数で、y = mx + nのように見えます。yが戻り値で、n(max - min),mであり、xがあなたの進捗値です。

リバース版の代わりにsigmoid functionの置換版を使用する必要があります。あなたはx = 0.5で中間値が必要で、0と1の間の値にのみ関心があります。また、Wikipediaの記事で示唆しているように、x = -6と6前後のy値はお互いにかなり近いのでx値を範囲[0, 1]から[-6, 6]にスケールするだけで済みます。次はあなたのアイデア

public static func map<T: FloatingPoint>(progress: T, min: T, max: T) -> T { 
    assert(progress >= 0) 
    assert(progress <= 1) 
    return min + ((max - min) * sigmoid(progress)) 
} 

private static func sigmoid(_ input: FloatingPoint) -> FloatingPoint { 
    let x = (input - 0.5) * 12.0 // scale the input value to be between -6 and 6 
    let ex = pow(M_E, x) // M_E is the Euler number and is a Double constant 
    return ex/(ex + 1) // return the result of the sigmoid function 
} 

を与える必要があり、私は前にFloatingPointを使ったことがないので、私はこれが動作する場合、いくつかの型の不一致があるかもしれませんわかりません。しかし、私はロジックがうまくいくはずだと思います。

+0

ありがとうございます。私はこれを使って遊び、その結果をあなたに知らせます。 FloatingPointは、Float値とDouble値の総称です。 –

+0

ありがとう@halileohalilei、私はあなたの答えを固定し、私が探していたものを得た。 –

関連する問題