Algoritmo Pergunta: precisa incrementar dinamicamente a partir 00FF00 para FF0000 ao longo do tempo, C # / Java

StackOverflow https://stackoverflow.com/questions/668263

  •  21-08-2019
  •  | 
  •  

Pergunta

Eu quero mudar a cor verde-clara para Dark Red ao longo do tempo (240 horas). A melhor maneira que eu posso ver é mudar o combo hex de 00FF00 para FF0000.

Eu não sei como contar dinamicamente até FF0000 de 00FF00 para a vida de mim. Estou procurando por um período de 10 dias, então provavelmente mais de 240 horas para incremento.

Alguém pode me ajudar?

Eu nunca tomou uma classe de algoritmos, então eu acho que pode ter algo a ver com este problema.

Se você tem uma maneira melhor de fazer isso, então deixe-me saber.

Eu estou procurando algum tipo de código aqui. Obrigado rapazes. Pode ser em qualquer língua, mas, inevitavelmente, serão convertidos para C #.

Foi útil?

Solução

Basta pensar nisso em termos de componentes. Mesmo que ele se parece com um grande número hexadecimal, é realmente três side-by-side.

No início, o vermelho é 0, o verde é 255 (FF), o azul é 0.
No final, o vermelho é 255, o verde é 0, o azul é 0.

Assim, cada (quantidade de tempo que você tem / 255), incremento vermelho por 1 e decréscimo verde por 1.

Outras dicas

Se você está indo de cor brilhante a cor brilhante como os valores hexadecimais sugerem, então você pode querer interpolate em HSV espaço , ao invés de espaço RGB. Aproxima espaço HSV como pensamos sobre a cor - matiz, saturação e valor. espaço RGB aproxima como as células sensíveis à luz em nossos olhos funcionam.

O gradiente é linear superior RGB interpolação a partir FF0000 para 00FF00. Seu valor médio é 7f7f00, um marrom lamacento.

O gradiente do meio é uma interpolação linear no espaço HSV. Como ambos FF0000 e 00FF00 são totalmente saturada e têm o mesmo valor (brilho), a interpolação mantém o mesmo brilho e saturação por toda parte, de modo que o valor central é ffff00 amarelo brilhante.

A terceira alternativa seria uma rotação de vector no espaço RGB, o que significaria a meados de valor é B4B400, (B4 hex = 180 dezembro = 255 / sqrt (2)), que está algures entre os dois efeitos. Isto é feito através do cálculo da magnitude de cada ponto final, então escalar o resultado da interpolação linear RGB por isso é a mesma magnitude, efetivamente varrendo o vetor em um arco no plano das duas cores e a origem. Como não temos realmente pesam cores diferentes igualmente para o brilho, ou ver de forma linear, não é exata, mas tem uma intensidade bastante uniforme em toda a sua varredura, enquanto o HSV é um pouco mais leve no meio, como ele tem dois valores em 100%.

removido ligação Imageshack mortos


Em Java, onde você tem HSB suportar o algoritmo é simples - obter o HSB dos valores finais, interpolate linear los como em outras respostas RGB, em seguida, converter criar uma cor com o h, s, valores v:

static Color hsvInterpolate ( float mix, Color c0, Color c1 ) {
    float[] hsv0 = new float[3];
    float[] hsv1 = new float[3];

    float alt = 1.0f - mix;

    Color.RGBtoHSB( c0.getRed(), c0.getGreen(), c0.getBlue(), hsv0 );
    Color.RGBtoHSB( c1.getRed(), c1.getGreen(), c1.getBlue(), hsv1 );

    float h = mix * hsv0 [ 0 ] +  alt * hsv1 [ 0 ];
    float s = mix * hsv0 [ 1 ] +  alt * hsv1 [ 1 ];
    float v = mix * hsv0 [ 2 ] +  alt * hsv1 [ 2 ];

    return Color.getHSBColor ( h, s, v );
}

Eu não acredito C # tem as conversões embutido, para que o código não é muito útil realmente.

static Color vectorInterpolate ( float mix, Color c0, Color c1 ) {
    float alt = 1.0f - mix;

    double x0 = c0.getRed();
    double y0 = c0.getGreen();
    double z0 = c0.getBlue();

    double x1 = c1.getRed();
    double y1 = c1.getGreen();
    double z1 = c1.getBlue();

    double mag0 = sqrt( x0*x0 + y0*y0 + z0*z0 );
    double mag1 = sqrt( x1*x1 + y1*y1 + z1*z1 );

    double x = mix * x0 + alt * x1;
    double y = mix * y0 + alt * y1;
    double z = mix * z0 + alt * z1;

    double mag  = mix * mag0 + alt * mag1;
    double scale = mag / sqrt( x*x + y*y + z*z );

    return new Color ( 
        clamp ( x * scale ),
        clamp ( y * scale ),
        clamp ( z * scale ) );
}

static int clamp ( double value ) {
    int x = (int) round ( value );

    if ( x > 255 ) return 255;
    if ( x < 0 ) return 0;
    return x;
}

Você provavelmente vai querer encontrar a interseção do vetor com a borda do cubo RGB em vez de simplesmente apertando-lo, mas, neste caso, não importa de qualquer maneira.


Como um adendo, é também vale a pena considerar o espaço HSY, que está mais perto de brilho percebido, como ilustrado pelo hélice cubo de Dave Green interpolações de cor.

TIME_REMAINING (valor varia de 0 a 239)

verde = 255 * (time_remaining / 239)
vermelho = 255 - verde
azul = 0

color = (vermelho, verde, azul)

aqui é uma resposta java rápida de vermelho para verde (OFC você pode mudar isso) valor é o tempo valuein atual e all é a soma do tempo de ...

public static String progressiveColor(int value, int all){

    int red = 255 - (int)((float)(value*255)/(float)all);
    int green = (int)((float)(value*255)/(float)all);
    return String.format("#%06X", (0xFFFFFF & Color.argb(255, red, green, 0)));

}

Aqui está o código Java de Pete traduzido em C # no caso de alguém estava procurando por isso. Ele funciona muito bem para os meus propósitos (preto para vermelho escuro e volta).

    static Color VectorInterpolate(float mix, Color c0, Color c1)
    {
        float alt = 1.0f - mix;

        double x0 = c0.R;
        double y0 = c0.G;
        double z0 = c0.B;

        double x1 = c1.R;
        double y1 = c1.G;
        double z1 = c1.B;

        double mag0 = Math.Sqrt(x0 * x0 + y0 * y0 + z0 * z0);
        double mag1 = Math.Sqrt(x1 * x1 + y1 * y1 + z1 * z1);

        double x = mix * x0 + alt * x1;
        double y = mix * y0 + alt * y1;
        double z = mix * z0 + alt * z1;

        double mag = mix * mag0 + alt * mag1;
        double scale = mag / Math.Sqrt(x * x + y * y + z * z);

        return Color.FromRgb(Clamp(x * scale), Clamp(y * scale), Clamp(z * scale));
    }

    static byte Clamp(double value)
    {
        var x = (int)Math.Round(value);

        if (x > 255) return 255;
        if (x < 0) return 0;
        return (byte) x;
    }
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top