質問

現在、さまざまな鋭さ(または感度)を適用するための機能を追加する必要があるコントロールがあります。問題は画像として最もよく示されています:

グラフhttp://img87.imageshack.us/img87/7886/control。 png

ご覧のように、X軸とY軸にはいずれも100の任意の制限があります-この説明で十分です。現在、私のコントロールは赤い線(線形の動作)ですが、他の3つの曲線(またはそれ以上)の機能を追加したいと思います。 3行のうち。開始点は常に0で、終了点は常に100です。

指数関数はあまりにも急すぎることは知っていますが、先への道は分からないようです。提案はありますか?

役に立ちましたか?

解決

図に示した曲線は、ガンマ補正曲線によく似ています。範囲の最小値と最大値は入力と同じままですが、グラフのように真ん中が曲がっているという考えがあります(これは、あなたが思うような円弧ではありません コサイン実装から取得します)。

グラフィカルには、次のようになります:

 alt text
(source: wikimedia.org

だから、それをインスピレーションとして、ここに数学があります...

xの値の範囲が0から1の場合、関数はかなり単純です:

y = f(x, gamma) = x ^ gamma

スケーリングのxmax値を追加します(つまり、x = 0から100)。関数は次のようになります。

y = f(x, gamma) = ((x / xmax) ^ gamma) * xmax

または別の方法:

y = f(x, gamma) = (x ^ gamma) / (xmax ^ (gamma - 1))

ゼロ以外のxminを追加する場合は、これをさらに一歩進めることができます。

ガンマが1の場合、線は常に完全に線形です(y = x)。 xが1より小さい場合、曲線は上に曲がります。 xが1より大きい場合、曲線は下に曲がります。ガンマの逆数値は値を元の値に変換します(x = f(y、1 / g)= f(f(x、g)、1 / g)。

好みやアプリケーションのニーズに応じてガンマ値を調整するだけです。ユーザーに「感度向上」の複数のオプションを提供したいので、ユーザーに-4(最低の感度)から0(変更なし)から4(ほとんどの場合)感度)、べき関数で内部ガンマ値をスケーリングします。つまり、ユーザーに(-4、-3、-2、-1、0、1、2、3、4)の選択肢を与えるが、それを(5.06、3.38、2.25、1.50、1.00のガンマ値に変換する、0.67、0.44、0.30、0.20)。

C#でのコーディングは次のようになります。

public class SensitivityAdjuster {
    public SensitivityAdjuster() { }
    public SensitivityAdjuster(int level) {
        SetSensitivityLevel(level);
    }
    private double _Gamma = 1.0;
    public void SetSensitivityLevel(int level) {
        _Gamma = Math.Pow(1.5, level);
    }
    public double Adjust(double x) {
        return (Math.Pow((x / 100), _Gamma) * 100);
    }
}

これを使用するには、新しいSensitivityAdjusterを作成し、ユーザーの好みに応じて感度レベルを設定し(コンストラクターまたはメソッドを使用し、-4から4が適切なレベル値となる可能性があります)、Adjust(x)を呼び出して取得します調整された出力値。合理的なレベルのより広い範囲またはより狭い範囲が必要な場合は、SetSensitivityLevelsメソッドでその1.5値を増減します。そしてもちろん、100はxの最大値を表します。

他のヒント

私は、あなたの要求を捕らえる(私が信じる)簡単な式を提案します。極端なケースである「クォーターサークル」全体を得るには、(1-cos((x * pi)/(2 * 100)))* 100 を使用します。

提案するのは、y = xとy =(1-cos((x * pi)/(2 * 100)))* 100の間の加重平均を取ることです。たとえば、線形に非常に近い(99%線形)には、次のようにします。

y = 0.99*x + 0.01*[(1-cos((x*pi)/(2*100)))*100]

またはより一般的には、線形性のレベルがLであり、区間[0、1]にある場合、式は次のようになります。

y = L*x + (1-L)*[(1-cos((x*pi)/(2*100)))*100]

編集: cos(x / 100) cos((x * pi)/(2 * 100))に変更しました。cosの結果が[1,0]の範囲で、Xは[0,1]ではなく[0、pi / 2]の範囲にある必要があります。最初のミスでごめんなさい。

多項式補間のようなものを探しているでしょう。二次/三次/四次補間は、質問で表示する種類の曲線を提供する必要があります。表示する3つの曲線の違いは、おそらく係数を調整するだけで実現できます(間接的に急峻度を決定します)。

0から1の x y = x ^ p のグラフは、 p を1から変化させたときに望みどおりになります(赤い線が表示されます)。 p が増加すると、曲線はますます「押し込まれ」ます。 p は整数である必要はありません。

(0から100を得るためにスケーリングする必要がありますが、それを解決できると確信しています)

1つの変更を加えて、Rax Olgudの一般的なアイデアに投票します。

y = alpha * x + (1-alpha)*(f(x/100)*100)

代替テキストhttp://www4c.wolframalpha.com / Calculate / MSP / MSP4501967d41e1aga1b3i00004bdeci2b6be2a59b?MSPStoreType = image / gif& s = 6

where f(0)= 0、f(1)= 1、f(x)は超線形ですが、この「クォーターサークル」がどこにあるのかわかりません。アイデアは、1-cos(x)が適切な選択肢であるか、またはその理由です。

f(x)= x k をお勧めします。ここで、k = 2、3、4、5で、& alpha = 0の急勾配の望ましいデグレが得られます。値を選択してくださいkを固定数として、αを変化させて特定の曲線を選択します。

このような問題については、カーブからいくつかのポイントを取得して、カーブフィッティングプログラムにそれを投げることがよくあります。それらの束はそこにあります。 こちらは7日間の無料試用版です。

さまざまなモデルを試すことで多くのことを学びました。多くの場合、非常に単純な式を取得して曲線に近づけることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top