Поколение градиентов RGB


18

Соревнование

С учетом двух заглавных шестнадцатеричные строки (длинные оба 6 символов, XXXXXX и YYYYYY) , представляющий значения RGB ( в диапазоне от 000000до FFFFFFвключительно), а положительный ненулевой число N, отображать линейный переход из N + 2 цветов , полученных от XXXXXX до YYYYYY это привело бы к цветовому градиенту.

пример

вход

FF3762
F08800
9

Выход

Обратите внимание, что в нашем примере я запросил 9 промежуточных шагов между двумя цветами, поэтому 11 строк будут отображаться от начального цвета до конечного цвета

FF3762
FD3F58
FC474E
FA4F44
F9573A
F75F31
F66727
F46F1D
F37713
F17F09
F08800

Предостережения

Несмотря на то, что я прошел простой линейный процесс получения целочисленных значений для промежуточных цветов перед их преобразованием обратно в шестнадцатеричное, ваши методы могут отличаться. Пожалуйста, подумайте о том, как можно округлить ваши цифры соответственно.

тестирование

Чтобы сделать это интересным, я предоставил фрагмент, позволяющий тестировать ваш код, включая кнопку, чтобы предоставить вам два случайных цвета для проверки вашего кода. Отображать результаты не обязательно, но это приветствуется!

c1=()=>('00000'+(Math.random()*(1<<24)|0).toString(16)).slice(-6);

$("#col").click(function(){
  alert("Your two colors are: "+c1()+" and "+c1()+".");
});
        
$("#colors").blur(function(){
  $("#test").empty();
	var colArr = $("#colors").val().split("\n");
	for(c in colArr){
  	$("#test").append('<div class="tester" style="background-color:#'+colArr[c]+';">'+colArr[c]+'</div>')
  }
  
});
.tester{height: 20px;
width: 60px;padding: 4px;border: 1px solid black;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="col">Your two colors</button><br />
<textarea id="colors"></textarea>
<div id="test">

</div>

1) Вы можете получить доступ к двум случайным цветам для теста, нажав на кнопку «Ваши два цвета». 2) Количество промежуточных шагов будет таким же, как количество символов в вашем имени пользователя PPCG, включая пробелы, в случае «WallyWest» это будет 9 (как в моем примере выше). 3) Запустите ваш код с двумя цветами и числом, и после того, как у вас будет сгенерированный список, у вас есть возможность вставить свой вывод в текстовую область и убрать с него вкладки, чтобы получить сгенерированный градиент цвета.

Мой пример показан здесь:

Градиенты

Я должен признать, это выглядит довольно круто!

Обратите внимание: как я уже говорил, показывать результаты тестирования с использованием фрагмента необязательно, но это рекомендуется! :)

Выход

Вывод списка должен быть в форме N + 2 наборов 6-значных шестнадцатеричных чисел, разделенных переводом строки (\ n), как показано в моем примере выше. Вывод может быть в виде отдельных строк, списка, разделенного пробелами / запятыми, массива или чего-либо, что лучше всего подходит для вашего языка ... (Спасибо @nimi за заголовок) Пожалуйста, помните, что если вы планируете тестировать свой код с фрагмент, однако вы отделяете каждый «цвет» зависит от вас.

правила

Это код-гольф, поэтому самое короткое решение в байтах будет признано победителем. Никаких лазеек , естественно. Входные данные должны принимать две строки и число (которое, как я уже сказал, будет эквивалентно количеству букв в вашем имени пользователя на PPCG, таким образом, ваш результирующий вывод всегда будет иметь длину не менее трех строк).



Отметил и обновил ... Спасибо за
помощь

Из любопытства, используют ли графические приложения, такие как Illustrator, линейные градиенты или градиенты в некотором воспринимаемом цветовом пространстве? Я могу видеть варианты использования для обоих (возможно, вы делаете преобразование для восприятия позже, например, текстуры для игры).
Роберт Фрейзер

Ответы:


1

MATL , 31 байт

2+1yhjjh2e!1ZA3e!b:1&Ynk8W5Y2Za

При этом используется линейная интерполяция с округлением вниз. Формат ввода

9
FF3762
F08800

Попробуйте онлайн!

Графический вывод, 31 байт

2+1yhjjh2e!1ZA3e!b:t2YG1&Ynk2ZG

Это результат для входов

5
FF3762
F08800

введите описание изображения здесь

Попробуйте это в MATL Online ! Переводчик в настоящее время экспериментальный. Если вы ничего не получили, обновите страницу и снова нажмите «Выполнить».


4

JavaScript (ES6), 130 байт

g=
(f,t,n)=>[...Array(++n+1)].map((_,i)=>f.replace(/../g,(e,j)=>((`0x${e}`*(n-i)+`0x${t[j]+t[j+1]}`*i)/n|256).toString(16).slice(1)))
;
p=_=>g(f.value,t.value,+n.value).map(e=>o.insertRow().insertCell().appendChild(document.createTextNode(e)).parentNode.bgColor=e);
<input id=f value=e14f09><input id=t value=9a04f6><input id=n value=4 type=number><input type=button onclick=p() value=Go!><table id=o bgcolor=black cellpadding=4>


3

Dyalog APL , 44 байта

Запрашивает N , затем B eginning-color, затем E- end-color. Требуется ⎕IO←0по умолчанию во многих системах.

h[↑⌊B∘+¨(⍳2+N)×(-/E B←(h←⎕D,⎕A)∘⍳¨⍞⍞)÷1+N←⎕]

h[... ]индекс в h (который имеет значение, когда мы заканчиваем оценку содержимого скобки)

N←⎕запрос на номер N (4)

1+добавить один к N (5)

(... используйте это, чтобы разделить результат ...

  ⍞⍞ подсказка для двухсимвольных строк ["7E0E7E", "FF3762"]

  (... )∘⍳¨найти индексы символов каждой строки в ...

   ⎕D,⎕A D igits следует A lphabet

   h←назначен на ч

  теперь у нас есть "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"

  E B←назначить индексы E и B [[7,14,0,14,7,14], [15,15,3,7,6,2]]

  -/вычесть и заключить B из E [[-8, -1, -3,7,1,12]]

  результат пока [[-1.6, -0.2, -0.6,1.4,0.2,2.4]]

(... умножить это на ...

  2+Nдва плюс N (6)

   первые целые числа [0,1,2,3,4,5]

 это дает нам [[0,0,0,0,0,0], [- 1,6, -0,2, -0,6,1,4,0,2,2,4], [- 3,2, -0,4, -1,2,2,8,0,4,4,8 ], ...]

B∘+¨добавить B к каждому [[15,15,3,7,6,2], [13.4,14.8,2.4,8.4,6.2,4.4], [11,8,14,6,1,8,9,8,6,4,6,8], ... ]

округлить [[15,15,3,7,6,2], [13,14,2,8,6,4], [11,14,1,9,6,6], ...]

составить список списков в таблицу

[[15,15, 3, 7, 6, 2]
 [13,14, 2, 8, 6, 4]
 [11,14, 1, 9, 6, 6]
 [10,14, 1,11, 6, 9]
 [ 8,14, 0,12, 6,11]
 [ 7,14, 0,14, 7,14]]

здесь мы индексируем в ч , давая

[["F","F","3","7","6","2]
 ["D","E","2","8","6","4]
 ["B","E","1","9","6","6]
 ["A","E","1","B","6","9]
 ["8","E","0","C","6","B]
 ["7","E","0","E","7","E]]

который так же, как

[["FF3762"]
 ["DE2864"]
 ["BE1966"]
 ["AE1B69"]
 ["8E0C6B"]
 ["7E0E7E"]]

и печатает как

FF3762
DE2864
BE1966
AE1B69
8E0C6B
7E0E7E

градиент

Попробуй APL онлайн!


Хорошо сделано! Переход выглядит великолепно!
WallyWest

@WallWest Спасибо. Это, вероятно, другой линейный переход, чем у большинства: каждая буква передается отдельно.
Адам

2

Pyth - 35 байт

Ужасно играл в гольф, просто сдался.

j++hQsMCm.HMsM:F+dc-FdvzCmiR16cd2Qe

Попробуйте это онлайн здесь .

Пример:

пример


Я считаю 11 строк градиента, хотя ваше имя PPCG имеет только 8 букв ... Так почему бы не ввести 7cb472 93fb8a 8и получить только 10 строк вывода при тестировании вашего кода?
WallyWest

@WallyWest полностью пропустил ту часть в OP по поводу имени пользователя, я просто использовал 9, потому что вы сделали, исправляя.
Maltysen

Обновление @WallyWest
Maltysen

Эй, Малтисен, градиент кажется немного странным ... у тебя есть две ссылки 93fb8a... Ваш код вывел две строки одного и того же значения?
WallyWest

2

PowerShell v2 +, 176 159 150 байт

param($a,$b,$n)$x=$a-split'(..)'-ne'';$a;++$n..1|%{$j=$_;-join($x=$x|%{"{0:x2}"-f(+"0x$_"-[int]((+"0x$_"-"0x$(($b-split'(..)'-ne'')[$i++%3])")/$j))})}

Принимает входные данные в виде двух строк и числа, а затем преобразует начальную строку в массив строк, разделенных на каждые два символа, и сохраняет их в $x. Затем мы выводим в $aкачестве нашего начального раздела и выполняем цикл от ++$nдо 1(для обеспечения правильного размещения ограждения).

Каждая итерация устанавливает значение помощника $jдля текущего номера (используется позже, чтобы убедиться, что мы получили правильное количество шагов между тем, где мы находимся в данный момент, к нашему месту назначения) и вычисляет следующий шаг на основе цикла $x.

Каждый внутренний цикл - это просто назначение. Мы устанавливаем $xв соответствующем месте, равном новой строке, "{0:x2}"используя -fоператор ormat. x2Здесь задает вывод шестнадцатеричного двузначного, а вход правой стороны -fоператора. PowerShell имеет встроенный шестнадцатеричный-десятичный оператор 0x, так что это длинное вложенное в паренсы выражение использует этот оператор для преобразования текущего шестнадцатеричного числа в числа, вычитая, чтобы найти разницу, которая еще предстоит сделать (это делается путем динамического разделения $bздесь, как мы это делали $a, и используя модуль по модулю, чтобы выбрать правильный элемент), деление на $jоставшиеся шаги, приведение к[int] (PowerShell выполняет банковское округление по умолчанию) и вычитает этот шаг из текущего гекса, чтобы получить то, каким должен быть наш следующий гекс.

Результат этого вычисления сохраняется в $xвиде трех шестнадцатеричных элементов. Это заключено в скобки для создания копии в конвейере и -joinобъединено в одну строку. Все эти результирующие строки остаются в конвейере, и вывод через неявный Write-Outputпроисходит при выполнении программы.


пример

Мне дали 0ba7c5 и 6c0e50 для моих двух цветов, и в TimmyD есть 6 символов.

PS C:\Tools\Scripts\golfing> .\rgb-gradients-generation.ps1 '0ba7c5' '6c0e50' 6
0ba7c5
1991b4
277ba3
356592
434f82
513971
5f2361
6c0e50

Пример градиента


1

Python 2, 189 байт

w='[int(%s[i:i+2],16)for i in range(0,6,2)]'
def f(a,b,n):
 l=lambda x,y:'%02x'%int((x*(n-i)+y*i)/n);c,d,e=eval(w%'a');f,g,h=eval(w%'b');n+=1
 for i in range(n+1):print l(c,f)+l(d,g)+l(e,h)

скриншот градиента


Великолепная пара цветов, @AndrewEpstein ... Отличная работа с кодом!
WallyWest

1

[Groovy] Окончательное обновление (199 байт) - согласно запросу

Non-гольф

def g(a,b,n){
  (0..(1.0/n)).collect{
    c->
    x={s->s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}};
    (0..2).collect {
      (int)(x(a).get(it)*n*c+x(b).get(it)*(1-n*c))
    }.collect {
      String.format("%X", it)
    }.join()
  }
}
g('FFFFFF','000000',1/10​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​​)​​​​​​​​​​​​​​

Гольф

g(a,b,n){(0..(1.0/n)).collect{c->x={s->s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}};(0..2).collect {(int)(x(a).get(it)*n*c+x(b).get(it)*(1-n*c))}.collect{String.format("%X",it)}.join()}}

Попробуйте финальный здесь: https://groovyconsole.appspot.com/script/5130696796405760


СТАРЫЕ ВЕРСИИ НИЖЕ, ОТКЛОНЕННЫЕ ОП


Groovy (123 байта)

Гольф

def g(r,g,b,r2,g2,b2,s){(1..(1.0/s)).collect{c->[(int)(r*s*c+r2*(1-s*c)),(int)(g*s*c+g2*(1-s*c)),(int)(b*s*c+b2*(1-s*c))]}}

Non-гольф

def g(r,g,b,r2,g2,b2,s){
  (1..(1.0/s)).collect {
    c ->
    [(int)(r*s*c+r2*(1-s*c)),(int)(g*s*c+g2*(1-s*c)),(int)(b*s*c+b2*(1-s*c))]
  }
}

входные

r,g,b -> Starting RGB Color
r2,g2,b2 -> Ending RGB Color
s -> Gradient step

Пример вывода

(00,00,00,255,255,255,.5)

результаты в

[
  [255, 255, 255]
  [127, 127, 127]
  [0, 0, 0]
]

Попробуйте сами: https://groovyconsole.appspot.com/script/5184465357766656

С включенными шестнадцатеричными преобразованиями

Думаю, я тоже обманываю ... Вот сценарий с использованием hex:

Новый код с шестнадцатеричными преобразованиями:

​    def g(r,g,b,r2,g2,b2,s){
      (0..(1.0/s)).collect {
        c ->
        String.format("%X", ((int)(r*s*c+r2*(1-s*c)))) +  String.format("%X", ((int)(g*s*c+g2*(1-s*c)))) + "" +  String.format("%X", ((int)(b*s*c+b2*(1-s*c))))
      }
    }

    g(126,34,166,218,26,33,0.0625)​

188 символов при игре в гольф:

def g(r,g,b,r2,g2,b2,s){(0..(1.0/s)).collect {c->String.format("%X",((int)(r*s*c+r2*(1-s*c))))+String.format("%X",((int)(g*s*c+g2*(1-s*c))))+String.format("%X",((int)(b*s*c+b2*(1-s*c))))}}

Вывод от 000000 до FFFFFF и 16 (длина имени пользователя)

g(00,00,00,255,255,255,0.0625).each{println it}​

Монохроматический градиент с 1/16 ступенями


Err ... немного неверно, использовалась оригинальная версия "(0 .. (1.0 / s))", должно было быть "(1 .. (1.0 / s))".
Волшебная Урна Осьминога

1
Привет @carusocomputing ... Входные данные должны состоять из двух шестнадцатеричных строк и целого числа ... Я не уверен, что Groovy может принять ввод таким способом, но вы не совсем прибили краткое изложение ... Не могли бы вы обновить Ваш код, основанный на вводе, упомянутом в разделе «Задачи»?
WallyWest

{s-> s.split("(?<=\\G.{2})").collect{Integer.parseInt(it,16)}}('FFFFFF') Результаты в [255,255,255] Я могу добавить 62 байта в мой код, используя это преобразование, если вы действительно этого хотите.
Волшебная Урна Осьминога

1
Уолли, я добавил обновленную версию и увеличил свой окончательный счетчик байтов до 199 с включенными преобразованиями.
Волшебная Урна Осьминога

1

R, 68 байт

Есть встроенная функция, которая интерполирует два цвета:

a=scan(,'')
colorRampPalette(paste0("#",a[1:2]))(as.numeric(a[3])+2)

Входные данные:

d9e7a5
3ef951
15

Вывод: вектор со значениями

"#D9E7A5" "#CFE89F" "#C5E99A" "#BBEA95" "#B2EB90" "#A8EC8A" "#9EED85" "#95EE80"
"#8BF07B" "#81F175" "#78F270" "#6EF36B" "#64F466" "#5BF560" "#51F65B" "#47F756"
"#3EF951"

Спецификация цвета в R требует хеш-символа.

Цветовая гамма

Давайте построим что-то вроде функции:

filled.contour(outer(1:20, 1:20, function(x,y) sin(sqrt(x*y)/3)),
    col = colorRampPalette(paste0("#",a[1:2]))(as.numeric(a[3])+2))

грех (SQRT (х * у) / 3)


Хороший ответ, но в кратком изложении предлагается использовать столько шагов, сколько есть в вашем имени пользователя PPCG, при этом подсчет места составляет 15 ... Не могли бы вы обновить свой ответ на основе FF3762 F08800 15?
WallyWest

@WallyWest Извините, я пропустил ту часть, где один получает два цвета и считает свою длину имени пользователя. Теперь ответ должен полностью соответствовать спецификации!
Андрей Костырка

1

C 175 169 168 байт

i;j;x[6];f(a,b,n)char*a,*b;{char*f="%2x%2x%02x";for(n++;i<=n;i++,puts(""))for(j=sscanf(a,f,x,x+1,x+2)-sscanf(b,f,x+3,x+4,x+5);j++<printf(f+6,x[j]+(x[j+3]-x[j])*i/n););}

Ungolfed:

int i, j;
int x[3], y[3];

f(char *a, char *b, int n) {
  sscanf(a, "%2x%2x%2x", &x[0], &x[1], &x[2]);
  sscanf(b, "%2x%2x%2x", &y[0], &y[1], &y[2]);

  for(i = 0, n++; i <= n; i++) {
    for(j = 0; j < 3; j++)
      printf("%02x", x[j] + (y[j] - x[j]) * i / n);
    puts("");
  }
}

Спасибо @ h-walters за то, что сбрили 5 байтов!


Напомните мне, что putsделает синтаксис снова?
WallyWest

Это как printf(), но не делает никакого форматирования, вместо этого он просто печатает заданную строку как есть, и добавляет новую строку.
Г. Слипен

Ах, так что нет никакого способа играть в гольф, что ... Это немного ограничительно, не так ли?
WallyWest

"так что нет никакого способа игры в гольф, что" ... Конечно, есть! Переместиться puts("")в третью часть первого цикла for ( ;после становления ,перед) ... +0 байт. Однако это позволяет удалить фигурные скобки после второго цикла ... -2 байта. Вы можете сохранить еще 1 байт, удалив 3 из j<3, и заменив его своим printfоператором (это подлый ... printf вернет только 2, но все равно придется оценивать в третий раз).
H Уолтерс

... можно сохранить еще два байта, вычитая возвращаемые значения sscanf друг из друга (получая 0), и используя их вместо литерала 0в j=0. После того как все будет готово, ваша программа должна быть на 5 байт короче и не менее чем на 50% чужой.
H Уолтерс

1

sh + ImageMagick, 81 байт

convert -size 1x$((2+$3)) gradient:#$1-#$2 -depth 8 txt:-|grep -o "[A-F0-9]\{6\}"

использование:

> ./grad.sh FF3762 F08800 9
FF3762
FE3F58
FC474E
FB4F45
F9573B
F86031
F66827
F5701D
F37814
F2800A
F08800

(«-depth 8» не требуется, если ваш IM скомпилирован с 8bpp по умолчанию)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.