2

Color.FromArgbブラシの色を決定するために to を使用しています。たとえば、これを使用してPen p= new Pen(new SolidColorBrush(Color.FromArgb(95, 255, 0, 0)), 6);これの問題は、ブラシの 4 色 (赤、オレンジ、黄、緑) を使用したいということです。そして、この条件の値に応じて、色が特定の透明度で選択されるという条件があります。これに関する問題は、2 つの異なる色の間の遷移です。たとえば、緑から黄色、またはオレンジから赤に変わります。色が突然変化するので、これは望ましくありません。さまざまな色の間をスムーズに移行したいので、たとえばオレンジから赤に、赤くなるまでさまざまな程度のオレンジを取りたいと思っています。以下は、私が何をしたかを明確にするための私のコードのスナップショットです。の値に応じて以下に示すようにX色は特定の強度で決定されますが、問題は、の最後の値がX10を意味し、現在の値が11色が黄色であることを意味する場合です。滑らかさの程度。そして、HSV を使用することでこの問題を解決できるのではないかと考えました。そこで、アドバイスできる人がいたら教えてください。

for(X=0; X<=40; X++)
//this is green phase
if (X == 0)
    P = new Pen(new SolidColorBrush(Color.FromArgb(75, 0, 255, 0)), 6);
else if (X == 1)
    P = new Pen(new SolidColorBrush(Color.FromArgb(77, 0, 255, 0)), 6);
else if (X == 2)
    P = new Pen(new SolidColorBrush(Color.FromArgb(79, 0, 255, 0)), 6);
else if (X == 3)
    P = new Pen(new SolidColorBrush(Color.FromArgb(81, 0, 255, 0)), 6);
else if (X == 4)
    P = new Pen(new SolidColorBrush(Color.FromArgb(83, 0, 255, 0)), 6);
else if (X == 5)
    P = new Pen(new SolidColorBrush(Color.FromArgb(85, 0, 255, 0)), 6);
else if (X == 6)
    P = new Pen(new SolidColorBrush(Color.FromArgb(87, 0, 255, 0)), 6);
else if (X == 7)
    P = new Pen(new SolidColorBrush(Color.FromArgb(89, 0, 255, 0)), 6);
else if (X == 8)
    P = new Pen(new SolidColorBrush(Color.FromArgb(91, 0, 255, 0)), 6);
else if (X == 9)
    P = new Pen(new SolidColorBrush(Color.FromArgb(93, 0, 255, 0)), 6);
else if (X == 10)
    P = new Pen(new SolidColorBrush(Color.FromArgb(95, 0, 255, 0)), 6);

    // this is yellow phase
else if (X == 11)
    P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 255, 0)), 6);
else if (X == 12)
    P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 255, 0)), 6);
else if (X == 13)
    P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 255, 0)), 6);
else if (X == 14)
    P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 255, 0)), 6);
else if (X == 15)
    P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 255, 0)), 6);
else if (X == 16)
    P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 255, 0)), 6);
else if (X == 17)
    P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 255, 0)), 6);
else if (X == 18)
    P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 255, 0)), 6);
else if (X == 19)
    P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 255, 0)), 6);
else if (X == 20)
    P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 255, 0)), 6);

    // this is orange phase
else if (X == 21)
    P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 127, 0)), 6);
else if (X == 22)
    P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 127, 0)), 6);
else if (X == 23)
    P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 127, 0)), 6);
else if (X == 24)
    P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 127, 0)), 6);
else if (X == 25)
    P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 127, 0)), 6);
else if (X == 26)
    P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 127, 0)), 6);
else if (X == 27)
    P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 127, 0)), 6);
else if (X == 28)
    P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 127, 0)), 6);
else if (X == 29)
    P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 127, 0)), 6);
else if (X == 30)
    P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 127, 0)), 6);

    //this is red phase
else if (X == 31)
    P = new Pen(new SolidColorBrush(Color.FromArgb(75, 255, 0, 0)), 6);
else if (X == 32)
    P = new Pen(new SolidColorBrush(Color.FromArgb(77, 255, 0, 0)), 6);
else if (X == 33)
    P = new Pen(new SolidColorBrush(Color.FromArgb(79, 255, 0, 0)), 6);
else if (X == 34)
    P = new Pen(new SolidColorBrush(Color.FromArgb(81, 255, 0, 0)), 6);
else if (X == 35)
    P = new Pen(new SolidColorBrush(Color.FromArgb(83, 255, 0, 0)), 6);
else if (X == 36)
    P = new Pen(new SolidColorBrush(Color.FromArgb(85, 255, 0, 0)), 6);
else if (X == 37)
    P = new Pen(new SolidColorBrush(Color.FromArgb(87, 255, 0, 0)), 6);
else if (X == 38)
    P = new Pen(new SolidColorBrush(Color.FromArgb(89, 255, 0, 0)), 6);
else if (X == 39)
    P = new Pen(new SolidColorBrush(Color.FromArgb(91, 255, 0, 0)), 6);
else if (X == 40)
    P = new Pen(new SolidColorBrush(Color.FromArgb(93, 255, 0, 0)), 6);
4

1 に答える 1

4

多分あなたはこの答えを見てみる必要があります。メソッドおよびcolor クラスを使用してGetHue()、これらのパラメーターから新しい色を作成するのに役立ちます。GetSaturation()GetBrightness()

これを使用すると、開始色と終了色の色相を簡単に取得でき、ステップ サイズに応じて必要なだけ中間色を取得できます。

メソッドがあれば素晴らしいと思いませんか:

int numberOfIntermediateColors = 8;
IEnumerable<Colors> colorPalette = Color.Red.Range(Color.Green, numberOfIntermediateColors);

そして、ここにあります:

public static IEnumerable<Color> Range(this Color firstColor, Color lastColor, int count)
{
    float stepHueClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.Clockwise);
    float stepHueCounterClockwise = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count, Direction.CounterClockwise);

    if (Math.Abs(stepHueClockwise) >= Math.Abs(stepHueCounterClockwise))
        return Range(firstColor, lastColor, count, Direction.Clockwise);
    else
        return Range(firstColor, lastColor, count, Direction.CounterClockwise);
}

public static IEnumerable<Color> Range(this Color firstColor, Color lastColor, int count, Direction hueDirection)
{
    var color = firstColor;

    if (count <= 0)
        yield break;

    if (count == 1)
        yield return firstColor;

    float startingHue = color.GetHue();
    float stepHue = GetStepping(firstColor.GetHue(), lastColor.GetHue(), count - 1, hueDirection);
    var stepSaturation = (lastColor.GetSaturation() - firstColor.GetSaturation()) / (count - 1);
    var stepBrightness = (lastColor.GetBrightness() - firstColor.GetBrightness()) / (count - 1);
    var stepAlpha = (lastColor.A - firstColor.A) / (count - 1.0);

    for (int i = 1; i < count; i++)
    {
        yield return color;

        var hueValue = startingHue + stepHue * i;

        if (hueValue > 360)
            hueValue -= 360;

        if (hueValue < 0)
            hueValue = 360 + hueValue;

        color = FromAhsb(
                    Clamp((int)(color.A + stepAlpha), 0, 255),
                         hueValue,
                         Clamp(color.GetSaturation() + stepSaturation, 0, 1),
                         Clamp(color.GetBrightness() + stepBrightness, 0, 1));
    }

    yield return lastColor;
}

    public enum Direction
    {
        Clockwise = 0,
        CounterClockwise = 1
    }

private static float GetStepping(float start, float end, int count, Direction direction)
{
    var hueDiff = end - start;

    switch (direction)
    {
        case Direction.CounterClockwise:
            if (hueDiff >= 0)
                hueDiff = (360 - hueDiff) * -1;
            break;

        default:
            if (hueDiff <= 0)
                hueDiff = 360 + hueDiff;
            break;
    }

    return hueDiff / count;
}

private static int Clamp(int value, int min, int max)
{
    if (value < min)
        return min;

    if (value > max)
        return max;

    return value;
}

private static float Clamp(float value, float min, float max)
{
    if (value < min)
        return min;

    if (value > max)
        return max;

    return value;
}

透過性のないペンのリストを取得するには、次の簡単な方法を使用できます。

var startColor = Color.Green;
var endColor = Color.Red;
var penWidth = 6;

var rainbow = startColor.Range(endColor, 40, bla.Direction.CounterClockwise);
var pens = rainbow.Select(color => new Pen(color, penWidth))
                  .ToList();

// Somewhere else...
int x = RetrieveDesiredCondition();
var neededPen = pens[x];

私があなたの例で見ることができる限り、10色の各ブロックと合計4つのブロックに対して透明度を75から95まで反復させたいと思っています。その場合、おそらくこのアルゴリズムが役立つかもしれません:

var startColor = Color.Green;
var endColor = Color.Red;
var penWidth = 6;
var lowerTransparency = 75;
var higherTransparency = 95;
var stepsPerSection = 10;
var sections = 4;
var stepsNeeded = stepsPerSection * sections;

var transparencyRange = higherTransparency - lowerTransparency;
var stepSize = transparencyRange / stepsPerSection;
var rainbow = startColor.Range(endColor, stepsNeeded, Direction.CounterClockwise);
var rainbowWithTransparency = rainbow.Select((color, index) =>
{
    var step = (index % stepsPerSection) * stepSize;
    var neededTransparency = lowerTransparency + step;
    return Color.FromArgb(neededTransparency, color);
});

var pens = rainbowWithTransparency.Select(color => new Pen(color, penWidth))
                                  .ToList();

// Somewhere else...
int x = RetrieveDesiredCondition();
var neededPen = pens[x];
于 2013-09-16T06:55:57.580 に答える