私があなたの質問を正しく理解していれば、色のグラデーションのある形は本当に必要ありません。本当に必要なのは、次の 2 つのパラメーターによって色が決定される無地のオブジェクトです。
- カテゴリ (この例では cat1、cat2、cat3)
- 着色の程度 (列 3 の重み)
さらに、あなたの例の色は、小さい数字が白に近く、大きい数字が黒に近く、中央の数字が飽和色であるモデルに従っているようです。色空間に関しては、これは、ウィキペディアのこの写真に示されているように、色相、彩度、明度の色空間のようなものを示唆しています。
これを上記の例に戻すと、0.0 に近い重みは二重円錐の上部近くにあり、10.0 に近い重みは二重円錐の下部近くにあり、カテゴリによって表される色は色相が固定されていると思われます。これらの重みによって調整される彩度(概念的にはダブルコーンの赤道付近)。
次の perl コードは、HSL カラーを RGB に変換します。これは、この StackOverflow answer から改作されました。これは、上でリンクしたウィキペディアのページから改作されました。これは、必要なソリューションの一部にすぎません。
##
## Converts an HSL color value to RGB. Conversion formula
## adapted from http://en.wikipedia.org/wiki/HSL_color_space.
## Assumes h, s, and l are contained in the set [0, 1] and
## returns r, g, and b in the set [0, 255].
##
## @param Number h The hue
## @param Number s The saturation
## @param Number l The lightness
## @return Array The RGB representation
##
sub hsl_to_rgb
{
my ($h, $s, $l) = @_;
my ($r, $g, $b);
if ($s == 0)
{
$r = $g = $b = $l; ## achromatic
} else
{
sub hue2rgb
{
my ($p, $q, $t) = @_;
while ($t < 0) { $t += 1; }
while ($t > 1) { $t -= 1; }
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;
}
my $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
my $p = 2 * $l - $q;
$r = hue2rgb($p, $q, $h + 1/3);
$g = hue2rgb($p, $q, $h);
$b = hue2rgb($p, $q, $h - 1/3);
}
return [ int($r * 255), int($g * 255), int($b * 255) ];
}
この関数は、(0, 1.0, 0.5)
純粋な赤などの形式で HSL カラーを取得し、形式の RGB トリプレットを返します[ 255, 0, 0 ]
。これで、パズルの 1 ピースが得られます。
問題の説明からわかることに基づいて、カテゴリ別にソートされた、色相と彩度の観点からおそらく表現できる基本色のセットがあります。このようなもの:
my %cat_colors =
( # Hue Saturation
cat1 => [ 0.00000, 1.00000 ], # Red
cat2 => [ 0.16667, 1.00000 ], # Yellow
cat3 => [ 0.33333, 1.00000 ], # Green
);
OPによる更新:これは素晴らしいです。より多くのカテゴリに色を追加する場合、「色相」の値は次の Web サイトで確認できます: http://www.color-hex.com/。たとえば、この Web サイトでは、赤の HSL が : であると述べていることに注意してください0.00 1.00 0.50
。
注: これらの色を試してみたいと思うことは間違いありません。Photoshop や、さまざまな色空間で色を表示できるその他のツールを使用している場合は、各カテゴリの「ベース」カラーを正確に選択するのに役立ちます。上記のhsl_to_rgb
コードでは、色相と彩度の値を [0, 1] の範囲にスケーリングする必要があります。
これを上で指定した重みパラメーターにどのように適用しますか? 上で述べたように、HSL の明度パラメータに直接マッピングされているように見えます。ウェイト 0.0 は白にマッピングされ、ウェイト 10.0 は黒にマッピングされます。(少なくとも、あなたのスケッチを考えると、それは良い出発点のように思えます。) ただし、HSL では、1.0 は白で、0.0 は黒です。したがって、重量を明度にマッピングするには、次のような式が必要です。
$lightness = 1 - ($weight / 10);
これを関数でラップできます:
sub weight_to_light
{
return 1 - ($_[0] / 10);
}
hsl_to_rgb
式の最後の部分は、 によって返された RGBを HTML が処理できるものにマッピングすることです。それは実際には非常に簡単です。次の短い関数は、R、G、B 値の配列をhsl_to_rgb
HTML 対応の 16 進数文字列に変換します。
sub rgb_to_html_hex
{
return sprintf "#%.2X%.2X%.2X", @{ $_[0] };
}
つまり、すべてをまとめると、上記のカラーリング モデルに従ってオブジェクトに色を付けるために HTML で必要な文字列を含む、%col4
詳細を指定して名前を付け%col2
たハッシュを生成する場合は、上記の 2 つの関数、マッピング、そして、次のようないくつかのコード:%col3
%cat_colors
my %col4;
foreach my $key (keys %col2)
{
foreach my $i ( 0 .. scalar( @{ $col2{$key} } ) - 1 )
{
my $base_color = $cat_colors{ $col2{$key}->[$i] };
my $rgb_color = hsl_to_rgb( @$base_color,
weight_to_light( $col3{$key}->[$i] ) );
my $html_color = rgb_to_html_hex( $rgb_color );
$col4{$key}->[$i] = $html_color;
}
}
を生成したら、生成さ%col4
れた HTML 文字列を使用して個々のエンティティに色を付けることができます。私の最近の HTML は少し錆びていますが、 などの構成要素が一度は<FONT COLOR="#xxxxxx">
機能していたこと、そしてまだ機能している可能性があることはわかっています。計算された値から、構文的に有効で十分に最新の HTML を構築するのはあなたに任せます。
さて、あなたが解決しようとしている問題と、それをどのように解決する必要があるかについて、私はいくつかの大胆な仮定を立てたことを認めなければなりません。でも、私は一般的な球場にいると思います。ご不明な点がございましたら、お気軽にコメントを残してください。
そして...カットアンドペーストの便宜のために、サンプルデータセットとともに、上記のすべてのビットをスタンドアロンのテスト可能なperlプログラムにコピーした簡単なテストプログラムを次に示します。楽しみ!最後の 2 行では、YAML::XS を使用して計算された値をダンプする%col4
ので、それらが妥当かどうかを確認できます。
#!/usr/bin/perl -w
use Modern::Perl;
##
## Converts an HSL color value to RGB. Conversion formula
## adapted from http://en.wikipedia.org/wiki/HSL_color_space.
## Assumes h, s, and l are contained in the set [0, 1] and
## returns r, g, and b in the set [0, 255].
##
## @param Number h The hue
## @param Number s The saturation
## @param Number l The lightness
## @return Array The RGB representation
##
sub hsl_to_rgb
{
my ($h, $s, $l) = @_;
my ($r, $g, $b);
if ($s == 0)
{
$r = $g = $b = $l; ## achromatic
} else
{
sub hue2rgb
{
my ($p, $q, $t) = @_;
while ($t < 0) { $t += 1; }
while ($t > 1) { $t -= 1; }
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;
}
my $q = $l < 0.5 ? $l * (1 + $s) : $l + $s - $l * $s;
my $p = 2 * $l - $q;
$r = hue2rgb($p, $q, $h + 1/3);
$g = hue2rgb($p, $q, $h);
$b = hue2rgb($p, $q, $h - 1/3);
}
return [ int($r * 255), int($g * 255), int($b * 255) ];
}
sub rgb_to_html_hex
{
return sprintf "#%.2X%.2X%.2X", @{ $_[0] };
}
my %col1 = ( 'foo' => 1, 'bar' => 1 );
my %col2 = ('foo' => ['cat1','cat1','cat2'],
'bar' => ['cat3','cat2','cat3'] );
my %col3 = ('foo' => [2.3,1.2,1.0],
'bar' => [7.4,4.3,2.2]);
my %cat_colors =
( # Hue Saturation
cat1 => [ 0.00000, 1.00000 ], # Red
cat2 => [ 0.16667, 1.00000 ], # Yellow
cat3 => [ 0.33333, 1.00000 ], # Green
);
sub weight_to_light
{
return 1 - ($_[0] / 10);
}
my %col4;
foreach my $key (keys %col2)
{
foreach my $i ( 0 .. scalar( @{ $col2{$key} } ) - 1 )
{
my $base_color = $cat_colors{ $col2{$key}->[$i] };
my $rgb_color = hsl_to_rgb( @$base_color,
weight_to_light( $col3{$key}->[$i] ) );
my $html_color = rgb_to_html_hex( $rgb_color );
$col4{$key}->[$i] = $html_color;
}
}
use YAML::XS;
say Dump( \%col4 );