0

以下を達成するための優れたアルゴリズムを見つけようとしています。

私は2つのRGBカラーを持っています。1 つの色 (たとえば、赤 = 255, 0, 0) から始めて、何度か繰り返した後、青 (0, 0, 255) に変えたいと考えています。

私の現在のアルゴリズムは、単純に色の各コンポーネントの合計を取り、2 で割ります。これはトリックですが、速すぎます。反復ごとに、数値を元の値の 10 分の 1 だけ変更したいと考えています。したがって、反復 1 は色 (230、0、25) などを返す可能性があります。宛先の色も変更される可能性があることに注意してください。急に青の代わりに緑が欲しくなりました。

これを達成する良い方法を知っている人はいますか?私は数学を理解できないようです。

ありがとうございました!

4

2 に答える 2

0

古き良き数学は(いつものように)仕事をするので、より数学的なアプローチから始めましょう:

value-space RGB: [0,255]^3

Let a,b e RGB , step_w, step_no e N
f(a , b , step_w , step_no) = (a0 + (b0 - a0) / step_w * step_no , a1 + (b1 ...

数学から実際のコードへ:

Color f(Color a , Color b , int step_w , int step_no){
    return new Color(a.getRed() + (b.getRed() - a.getRed()) / step_w * step_no , a.getGreen() + (b.getGreen() - a.getGreen()) / step_w * step_no , ...);
}

step_w総ステップstep_no数とこれまでに実行されたステップ数です。forとfor 、および forの間の一致する色f(c1 , c2 , x , y)を返します。c1y = 0c2y = x0 < y < x

ただし、より自然に見える色変換 (ラボ カラー スペース、HSL など) には、より優れた方法があります。

于 2015-11-21T01:13:55.540 に答える
0

他の色空間と線形アプローチに関する 2 つの投稿が既にあります。

しかし、求めていることを正確に実行するアルゴリズムを本当に探している場合は、これを確認してください。

static class ColorChanger {
    static private final int    APPROACH_STEPS  = 10;

    private final Color         mStartColor;
    private final Color         mTargetColor;

    private int                 mApproachStep   = 0;
    private Color               mCurrentColor;

    public ColorChanger(final Color pStartColor, final Color pTargetColor) {
        mStartColor = pStartColor;
        mTargetColor = pTargetColor;
        System.out.println("\nStarting color is: " + mStartColor);
        System.out.println("Approaching target 1: " + mTargetColor);
    }

    public Color approach() {
        ++mApproachStep;
        if (mApproachStep <= APPROACH_STEPS) { // dont overshoot target color. could throw an exception here too
            final int newRedCode = nextColorCode(mStartColor.getRed(), mTargetColor.getRed());
            final int newGreenCode = nextColorCode(mStartColor.getGreen(), mTargetColor.getGreen());
            final int newBlueCode = nextColorCode(mStartColor.getBlue(), mTargetColor.getBlue());
            mCurrentColor = new Color(newRedCode, newGreenCode, newBlueCode);
        }
        System.out.println("\tNew step color is: " + mCurrentColor);
        return mCurrentColor;
    }

    private int nextColorCode(final int pCurrentCode, final int pTargetCode) {
        final int diff = pTargetCode - pCurrentCode;
        final int newCode = pCurrentCode + diff * mApproachStep / APPROACH_STEPS;
        return newCode;
    }

    public Color getCurrentColor() {
        return mCurrentColor;
    }

    public boolean isTargetColor() {
        return mApproachStep == APPROACH_STEPS;
    }
}

public static void main(final String[] args) {
    final Color startColor = Color.RED;
    final Color targetColor1 = Color.GREEN;
    final Color targetColor2 = Color.BLUE;
    final Color targetColor3 = Color.RED;

    // approach in only 5 steps, will by far not reach target color
    final ColorChanger cc1 = new ColorChanger(startColor, targetColor1);
    for (int i = 0; i < 5; i++) {
        cc1.approach();
    }

    // full approach #1
    final ColorChanger cc2 = new ColorChanger(cc1.getCurrentColor(), targetColor2);
    while (!cc2.isTargetColor()) {
        cc2.approach();
    }

    // full approach #2
    final ColorChanger cc3 = new ColorChanger(cc2.getCurrentColor(), targetColor3);
    for (int i = 0; i < ColorChanger.APPROACH_STEPS; i++) {
        cc3.approach();
    }

    System.out.println("Program ends");
}
于 2015-11-21T01:22:55.343 に答える