2015-11-21 3 views
0

Я пытаюсь найти хороший алгоритм для выполнения следующих действий:Алгоритма тенденция к заданному числу после п итераций

У меня есть два RGB цвета. Я начинаю с одного цвета (скажем, красного = 255, 0, 0), и после нескольких итераций я хочу, чтобы он стал синим (0, 0, 255).

Мой текущий алгоритм просто берет сумму каждого компонента цвета и делит на два, что делает трюк, но слишком быстро. На каждой итерации я хочу, чтобы числа менялись только на одну десятую от их первоначального значения. Итак, итерация 1 может вернуть цвет (230, 0, 25) и так далее. Имейте в виду, цвет назначения также может измениться. так что вдруг вместо синего я хочу зеленый.

Кто-нибудь знает, как это сделать? Я не могу понять математику.

Спасибо!

+2

Термин вы ищете Интерполяция. Кроме того, более приятный способ сочетания двух цветов делает это в цилиндрическом пространстве (см. HSL или HSV) вместо RGB. – Felk

ответ

0

Были еще два сообщения о других цветовых пространствах и линейном подходе.

Но если вы действительно ищете алгоритм, который делает именно то, что вы просите, проверить это:

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"); 
} 
+0

Извините, пришлось переделать это, чтобы работать точно так, как вы просили. – JayC667

+0

Большое спасибо, это именно то, что мне нужно! – Duffluc

0

математике Good Ol»делает работу (как обычно), так что давайте начнем с более математический подход:

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 количество шагов, выполненных до сих пор. f(c1 , c2 , x , y) вернет c1 для y = 0 и c2 для y = x и соответствующий цвет между ними для 0 < y < x.

Есть более приятные способы для цветопередачи, хотя (лабораторные цветовые пространства, HSL и т. Д.), Которые выглядят более естественными.

Смежные вопросы