Я не могу понять это. У меня есть масштабированный набор значений (0 … 1), с которым мне нужно связать цвета. Самый высокий (1) — красный, а самый низкий (0) — зеленый.
Я не могу найти, как получить цвет RGB между красным и зеленым для значения от 0 до 1.
Вот моя функция масштабирования, которую я собираюсь использовать для масштабирования значений:
function scale_value($value, $srcmin, $srcmax, $destmin = 0, $destmax = 1)
{
# How Far In Source Range Are We
$pos = (($value - $srcmin) / ($srcmax - $srcmin));
return ($pos * ($destmax - $destmin)) + $destmin;
}
Я полагал, что масштабирование их от 0 до 1 сделает следующую часть, с которой я борюсь, намного легче.
Вот одна очень грубая попытка сделать это, которую я придумал, но она провалилась.
function make_color($value)
{
$red = $value > 0.5
? (1 - 2 * ($value - 0.5) / 1)
: 1;
$green = $value > 0.5
? 1
: 2 * ($value / 1);
$blue = 0;
return "rgb($red,$green,$blue)";
}
У кого-нибудь есть опыт использования PHP для определения цвета, который будет использоваться для значения, которое находится между 1 и 0?
Нашел решение, конвертировав JS реализованное решение размещено здесь в PHP и изменив полярность красного на зеленый, чтобы красный был высоким, зеленый — низким.
Это выглядит так:
/**
* @param $value
* @param integer|float $min
* @param integer|float $max
* @return string
*/
function make_color($value, $min = 0, $max = .5)
{
$ratio = $value;
if ($min > 0 || $max < 1) {
if ($value < $min) {
$ratio = 1;
} else if ($value > $max) {
$ratio = 0;
} else {
$range = $min - $max;
$ratio = ($value - $max) / $range;
}
}
$hue = ($ratio * 1.2) / 3.60;
$rgb = hsl_to_rgb($hue, 1, .5);
$r = round($rgb['r'], 0);
$g = round($rgb['g'], 0);
$b = round($rgb['b'], 0);
return "rgb($r,$g,$b)";
}
Это также зависит от переводчика HSL в RGB, который я нашел на этом посте. Это в конечном итоге дает мне довольно хороший результат:
Спасибо за помощь.
Спасибо Мэтью Брауну за ссылку на его источник. И ссылка внутри этого с JSFiddle, которая работала в Javascript. Но версия Мэтью содержала функцию, которая не сработала в моем PHP, поэтому я преобразовал JSFiddle, включая все функции, и в результате получилось:
<html>
<head>
<style>
li {
display: block;
float: left;
width: 50px;
height: 50px;
margin: 2px;
}
hr {
clear: both;
}
</style>
<title>hi</title>
</head>
<body>
<?PHP
function hslToRgb($h, $s, $l){
# var r, g, b;
if($s == 0){
$r = $g = $b = $l; // achromatic
}else{
if($l < 0.5){
$q =$l * (1 + $s);
} else {
$q =$l + $s - $l * $s;
}
$p = 2 * $l - $q;
$r = hue2rgb($p, $q, $h + 1/3);
$g = hue2rgb($p, $q, $h);
$b = hue2rgb($p, $q, $h - 1/3);
}
$return=array(floor($r * 255), floor($g * 255), floor($b * 255));
return $return;
}
function hue2rgb($p, $q, $t){
if($t < 0) { $t++; }
if($t > 1) { $t--; }
if($t < 1/6) { return $p + ($q - $p) * 6 * $t; }
if($t < 1/2) { return $q; }
if($t < 2/3) { return $p + ($q - $p) * (2/3 - $t) * 6; }
return $p;
}
/**
* Convert a number to a color using hsl, with range definition.
* Example: if min/max are 0/1, and i is 0.75, the color is closer to green.
* Example: if min/max are 0.5/1, and i is 0.75, the color is in the middle between red and green.
* @param i (floating point, range 0 to 1)
* param min (floating point, range 0 to 1, all i at and below this is red)
* param max (floating point, range 0 to 1, all i at and above this is green)
*/
function numberToColorHsl($i, $min, $max) {
$ratio = $i;
if ($min> 0 || $max < 1) {
if ($i < $min) {
$ratio = 0;
} elseif ($i > $max) {
$ratio = 1;
} else {
$range = $max - $min;
$ratio = ($i-$min) / $range;
}
}
// as the function expects a value between 0 and 1, and red = 0° and green = 120°
// we convert the input to the appropriate hue value
$hue = $ratio * 1.2 / 3.60;
//if (minMaxFactor!=1) hue /= minMaxFactor;
//console.log(hue);
// we convert hsl to rgb (saturation 100%, lightness 50%)
$rgb = hslToRgb($hue, 1, .5);
// we format to css value and return
return 'rgb('.$rgb[0].','.$rgb[1].','.$rgb[2].')';
}
// build the color sample lists
for ($i=0; $i<=100; $i++) {
$list1.='<li style="background-color:'. numberToColorHsl($i/100, 0, 1) .'">'.$i."</li>\n";
$list2.='<li style="background-color:'. numberToColorHsl($i/100, 0.5, 1). '">'.$i."</li>\n";
$list3.='<li style="background-color:'. numberToColorHsl($i/100, 0, 0.6).'">' . $i . "</li>\n";
$list4.='<li style="background-color:'. numberToColorHsl($i/100, 0.3, 0.8).'">' . $i . "</li>\n";
}
echo "<br><hr>\n\n"; ?>
<hr>
full range
<ul id='list-1'></ul>
<?PHP echo $list1; ?>
<hr>
all below 0.5 is bad
<ul id='list-2'></ul>
<?PHP echo $list2; ?>
<hr>
all above 0.6 is ok
<ul id='list-3'></ul>
<?PHP echo $list3; ?>
<hr>
all below 0.3 is red, all above 0.8 is green
<ul id='list-4'></ul>
<?PHP echo $list4;