Вычислить разность шагов для 0,0 и 1,0 из заданного количества итераций. - PullRequest
0 голосов
/ 17 июня 2020

Я сделал эту функцию gradient(iteration), которая возвращает список значений HSL по порядку. Теперь проблема в том, что я не могу понять , как вычислить разницу в шагах, чтобы сохранить длину списка, возвращаемого функцией = no of итерация. (len(gradient(1000)) == 1000)

Вот функция gradient():

def gradient(iteration):
    """This function returns a list of HSL values
    of all the colors in an order."""

    ops = { '+': lambda c, step: min(1.0, c + step),
            '-': lambda c, step: max(0.0, c - step)}

    index = 0
    operation = '+'
    rgb, _list = [1.0, 0.0, 0.0], []
    combo = ((2,1,0), (2,0,1), (0,2,1), (0,1,2), (1,0,2), (1,2,0))
    step = 1 if iteration > get_len(1/255) else int(get_len(1/255)/iteration)
    step /= 200

    for i in range(iteration):
        if (rgb[combo[index][1]] == 1.0 and operation == '+') or \
           (rgb[combo[index][1]] == 0.0 and operation == '-'):
            operation = '-' if operation == '+' else '+'
            index += 1
            if len(combo)-1 <= index: break#index = 0
        rgb[combo[index][1]] = ops[operation](rgb[combo[index][1]], step)
        _list.append(rgb)
    return _list

What I ' Я пробовал до сих пор:

  1. Я создал функцию get_len, которая даст общую длину списка, заданного в соответствии с параметром шага. План состоит в том, чтобы попытаться найти точное значение шага по значению, возвращаемому get_len.

    def get_len(step):
        c = 1
        v = 1.0
        while True:
            v = max(0.0, v - step)
            if v == 0.0: break
            c += 1
        return c*5
    
  2. Далее я попытался исправить расчет для step и подошел очень близко с этим.

    step = 1 if iteration > get_len(1/255) else int(get_len(1/255)/iteration)
    step /= 200
    

Чтобы лучше понять, с чем я пытаюсь справиться, запустите этот код

# i and len(gradient(i)) should be equal.
for i in range(1,100):
    print(i, len(gradient(i)))

Например: -

Th ie изображение имеет 159 итераций.

image

Это изображение имеет 509 итераций.

image

В основном я пытаюсь изменить длину полосы градиента, но с любым целочисленным значением, присвоенным функции gradient(iteration).

1 Ответ

1 голос
/ 19 июня 2020

Код близок, но я считаю, что ошибка происходит из-за чрезмерного усложнения того, как вы думаете о step. Это значение просто должно быть правильным числом от go от 0 до 1 и наоборот для каждой комбинации, которую вы жестко запрограммировали. Ваша функция get_len выполняет следующую операцию: (step + 1) * 5, затем вы берете это значение и пытаетесь приблизиться к правильному размеру шага, заданному iteration. Его можно уменьшить до len(combo) / iteration, что даст вам правильное количество шагов при использовании операций +/-. Я думаю, это легче увидеть с помощью кода.

def gradient(iteration):
    """This function returns a list of HSL values
    of all the colors in an order."""

    ops = { '+': lambda c, step: min(1.0, c + step),
            '-': lambda c, step: max(0.0, c - step)}

    index = 0
    operation = '+'
    rgb, _list = [1.0, 0.0, 0.0], []
    combo = ((2,1,0), (2,0,1), (0,2,1), (0,1,2), (1,0,2), (1,2,0)) 

    step = len(combo) / iteration  # The right calculation

    for i in range(iteration):
        if (rgb[combo[index][1]] == 1.0 and operation == '+') or \
           (rgb[combo[index][1]] == 0.0 and operation == '-'):
            operation = '-' if operation == '+' else '+'
            index += 1
            if len(combo) <= index:  # Check isn't needed, but here for sanity
                print('Break with index', index)
                break
        rgb[combo[index][1]] = ops[operation](rgb[combo[index][1]], step)
        _list.append(rgb.copy())  # Make a copy to prevent mutation!
    return _list

Чтобы проверить правильность, запустите следующее, и вы увидите, что оператор print в break не запускается, вы не получите an AssertionError.

for i in range(1,100):
    assert i == len(gradient(i))

Обратите внимание, что я внес два исправления в ваш исходный код: в операторе break было неверное значение len(index) - 1 и добавлена ​​копия rgb в _list, чтобы вы не получали одно и то же значение RGB снова и снова.

Думаю, это ответ на ваш вопрос, дайте мне знать иначе.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...