알고리즘 질문 ​​: 시간이 지남에 따라 00ff00에서 FF0000으로 동적으로 증가해야합니다. C#/Java

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

  •  21-08-2019
  •  | 
  •  

문제

시간이 지남에 따라 밝은 녹색을 어두운 빨간색으로 바꾸고 싶습니다 (240 시간). 내가 볼 수있는 가장 좋은 방법은 HEX 콤보를 00FF00에서 FF0000으로 변경하는 것입니다.

나는 내 삶을 위해 00ff00에서 FF0000까지 동적으로 계산하는 방법을 모른다. 나는 10 일 동안을보고 있기 때문에 240 시간 이상 증가 할 가능성이 높습니다.

누구든지 나를 도울 수 있습니까?

나는 알고리즘 수업을받지 못했기 때문에이 문제와 관련이있을 수 있다고 생각합니다.

더 나은 방법이 있다면 알려주세요.

나는 여기에 어떤 종류의 코드를 찾고 있습니다. 감사합니다. 어떤 언어로든 가능하지만 필연적으로 C#로 변환됩니다.

도움이 되었습니까?

해결책

구성 요소 측면에서 생각해보십시오. 하나의 큰 16 진수 번호처럼 보이지만 실제로는 3 개의 나란히 있습니다.

처음에는 빨간색이 0이고 녹색은 255 (ff), 파란색은 0입니다.
결국, 빨간색은 255, 녹색은 0, 파란색은 0입니다.

따라서, 모든 (당신이 가진 시간의 양 / 255), 1만큼 빨간색을 증가시키고 녹색을 1 씩 감소시킵니다.

다른 팁

16 진수 값이 제안한대로 밝은 색에서 밝은 색상으로 가면 보간을 원할 수 있습니다. HSV 공간, RGB 공간보다는. HSV 공간은 색상 - 색조, 채도 및 값에 대한 우리의 생각에 근사합니다. RGB 공간은 우리 눈의 빛 민감성 세포가 어떻게 작동하는지 근사합니다.

상부 그라디언트는 FF0000에서 00FF에서 선형 RGB 보간입니다. 중간 값은 7f7f00, 진흙탕 갈색입니다.

중간 구배는 HSV 공간에서 선형 보간입니다. FF0000과 00FF00이 모두 포화되어 동일한 값 (밝기)을 가지므로 보간은 전체적으로 동일한 밝기와 채도를 유지하므로 중심 값은 밝은 노란색 FFFF00입니다.

세 번째 대안은 RGB 공간의 벡터 회전이며, 이는 중간 값이 B4B400, (B4 Hex = 180 Dec = 255 / sqrt (2))임을 의미하며, 이는 두 효과 사이에 있습니다. 이것은 각 엔드 포인트의 크기를 계산 한 다음 RGB 선형 보간 결과를 스케일링하여 동일한 크기가되어 두 가지 색상의 평면과 원점의 아크에서 벡터를 효과적으로 청소합니다. 우리는 실제로 밝기를 위해 다른 색상의 무게를 똑같이 무게를 가지거나 선형으로 보지 않기 때문에 정확하지는 않지만 스윕에 걸쳐 강도가 상당히 높지는 않지만 HSV One은 두 가지 값을 얻기 때문에 중간에 약간 가볍습니다. 100%

Dead Imageshack 링크를 제거했습니다


HSB가 지원하는 Java에서는 알고리즘이 간단합니다. 엔드 값의 HSB를 가져오고 다른 RGB 답변에서와 같이 선형 값을 보간 한 다음 h, s, 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 );
}

C#에 전환이 내장되어 있다고 생각하지 않으므로 코드는 실제로 사용되지 않습니다.

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;
}

당신은 아마도 벡터와 RGB 큐브의 가장자리와의 교차점을 단순히 클램핑하는 대신 RGB 큐브의 가장자리를 찾고 싶을 것입니다. 그러나이 경우 어느 쪽이든 중요하지 않습니다.


부록으로서, HSY 공간을 고려할 가치가 있습니다. 데이브 그린의 큐브 나선 색 보간.

time_remaining (값은 0에서 239까지 다양합니다)

green = 255 * (Time_Remaining / 239)
빨간색 = 255- 녹색
파란색 = 0

color = (빨간색, 녹색, 파란색)

다음은 빨간색에서 녹색으로 빠른 Java 답변입니다 (OFC는 변경할 수 있습니다) 값은 전류입니다. value시간과 all 시간의 합계 ...

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)));

}

다음은 누구나 찾을 경우 C#으로 번역 된 Pete의 Java 코드입니다. 그것은 내 목적에 적합합니다 (검은 색에서 짙은 빨간색과 뒤로).

    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;
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top