3

色のシーケンスを徐々に補間または変更する必要があるため、colorAからc​​olorB、colorC、colorDに戻り、colorAに戻ります。これは、ミリ秒単位の経過時間に基づく必要があります。ヘルプは大歓迎です(アルゴリズム、疑似コードは素晴らしいでしょう)。

RGBを使用していることに注意してください。これは、0〜255または0.0〜1.0の範囲である可能性があります。

これは私がこれまでに持っているものです。「timePeriod」ごとに色を変更する必要があります。経過時間の割合を計算して色を変更します。このコードの問題は、AからAに移行するときにジャンプすることです。 BからB、Cなど

int millisNow = ofGetElapsedTimeMillis();
int millisSinceLastCheck = millisNow - lastTimeCheck;
if ( millisSinceLastCheck > timePeriod ) {
    lastTimeCheck = millisNow;
    millisSinceLastCheck = 0;
    colorsIndex++;
    if ( colorsIndex == colors.size()-1 ) colorsIndex = 0;
    cout << "color indes: " << colorsIndex << endl;
    cout << "color indes: " << colorsIndex + 1 << endl;
}
timeFraction = (float)(millisSinceLastCheck) / (float)(timePeriod);
float p = timeFraction;
colorT.r = colors[colorsIndex].r * p + ( colors[colorsIndex+1].r * ( 1.0 - p ) );
colorT.g = colors[colorsIndex].g * p + ( colors[colorsIndex+1].g * ( 1.0 - p ) );
colorT.b = colors[colorsIndex].b * p + ( colors[colorsIndex+1].b * ( 1.0 - p ) );
colorT.normalize();

前もって感謝します

4

6 に答える 6

11

コードはほぼ正しいですが、逆方向に補間を行っています。つまり、B-> A、C-> B、D-> Cなどを補間しています。これにより、色を切り替えるときに不連続性が発生します。

これを置き換える必要があります:

colorT.r = colors[colorsIndex].r * p + ( colors[colorsIndex+1].r * ( 1.0 - p ) );

と:

colorT.r = colors[colorsIndex].r * (1.0 - p) + ( colors[colorsIndex+1].r * p );

他の回線についても同じです。

また、他の人が言っているように、RGBとは異なる色空間を使用すると、見栄えの良い結果が得られます。

于 2011-05-02T17:25:47.817 に答える
9

補間色を処理する方法は2つあります。1つは高速で簡単(あなたがしていること)で、もう1つは少し遅いですが、状況によっては見栄えが良くなります。

1つ目は、の明白で単純な方法です(x * s) + (y * (1-s))。これは、純粋な線形補間であり、名前が示すとおりに実行されます。ただし、特定の色のペア(たとえば、緑とオレンジ)では、真ん中にいくつかの厄介な色(汚れた茶色)が表示されます。これは、各コンポーネント(R、G、B)をラーピングしていて、組み合わせが不快な点があるためです。最も基本的なlerpが必要な場合は、これが必要なメソッドであり、コードはほぼ正しいです。

見栄えは良いが少し遅い効果が必要な場合は、HSL色空間で補間することをお勧めします。色相、彩度、および彩度はそれぞれ補間されるため、それらの間に期待する色が得られ、醜いものの大部分を回避できます。通常、色はある種のホイールで描画されるため、このメソッドはそれを認識しています(基本的なRGB lerpは、3本の個別の線で機能しているように機能します)。

HSL lerpを使用するには、RGB値を変換し、結果間でlerpを実行してから、元に戻す必要があります。このページには、そのために役立つ可能性のあるいくつかの式があり、このページには、それを処理するためのPHPコードがあります。

于 2011-05-02T17:22:13.583 に答える
1

R、G、およびBコンポーネントを補間すると、機能するコードが生成されます。欠点の1つは、数学的には同じであっても、作成するステップが必ずしも同じように見えるとは限らないことです。

それが気になる場合は、RGBからL * a * b *(人間の知覚により密接に対応するように設計されている)のようなものに値を変換し、それらの値を補間してから、補間された各値をRGBに戻すことができます。画面。

于 2011-05-02T17:21:33.740 に答える
1

あなたがすでに持っているものは非常によく見えますが、私は数学を少し単純化します:

int millisNow = ofGetElapsedTimeMillis();
int millisSinceLastCheck = millisNow % timerPeriod;
int colorsIndex = (millisNow / timerPerod) % (colors.size() - 1);


float p = (float)(millisSinceLastCheck) / (float)(timePeriod);
colorT.r = colors[colorsIndex+1].r * p + ( colors[colorsIndex].r * ( 1.0 - p ) );
colorT.g = colors[colorsIndex+1].g * p + ( colors[colorsIndex].g * ( 1.0 - p ) );
colorT.b = colors[colorsIndex+1].b * p + ( colors[colorsIndex].b * ( 1.0 - p ) );
colorT.normalize();
于 2011-05-02T17:28:51.030 に答える
0

私が現在取り組んでいるプロジェクトでこれを行っています。R、G、Bの値を個別に扱い、間にある「ステップ」の数に基づいてcolor1からcolor2に遷移します。離散値があるため、ルックアップテーブルのアプローチがありますが、浮動小数点でも同じことを実行して、RGB値を動的に計算することができます。

それでも質問がある場合は、Javaコードを投稿できます。

于 2011-05-02T17:14:43.023 に答える
-1

3つのコンポーネント(RBG)を分離し、従来の補間アルゴリズムを使用してそれぞれを個別に補間します。

于 2011-05-02T17:14:23.843 に答える