ترسم لي قوس قزح
-
06-07-2019 - |
سؤال
كيف يمكنك أن تذهب نحو اتخاذ مجموعة من الألوان RGB متباعدة بشكل متساو فوق الطيفية اللون ؟ بحيث تبدو وكأنها حقيقية قوس قزح.
المحلول
استخدم HSL بدلا من ذلك: إصلاح السطوع والتشبع وتختلف هوى 0-360، ثم تحويلها إلى RGB.
وHSL يصف الألوان كما ينظر إليها من قبل الناس. يصف RGB منهم أنها تستخدم من قبل الأجهزة. لذلك لا يمكنك حقا أن تفعل أي شيء ارضاء بصريا مباشرة باستخدام RGB.
نصائح أخرى
ويمكنك استخدام HSV لون الفضاء و السير عبر البعد هوى.
أبسط النهج هو أن تفعل الخطية (RGB) بين كل متتالية الزوج في هذا التسلسل:
#ff0000
الأحمر#ffff00
الأصفر#00ff00
الأخضر#00ffff
سماوي#0000ff
الأزرق#ff00ff
أرجواني#ff0000
العودة إلى الأحمر
هذا ينبغي أن تحصل على تقريبا نفس النتيجة التي تجتاح هوى القيم في هامبورغ أو الأعرج ، ولكن يتيح لك العمل مباشرة في RGB.لاحظ أن عنصر واحد فقط التغييرات لكل الاستيفاء ، الذي يبسط الأمور.وهنا الثعبان التنفيذ:
def rainbow():
r, g, b = 255, 0, 0
for g in range(256):
yield r, g, b
for r in range(255, -1, -1):
yield r, g, b
for b in range(256):
yield r, g, b
for g in range(255, -1, -1):
yield r, g, b
for r in range(256):
yield r, g, b
for b in range(255, -1, -1):
yield r, g, b
- الأحمر (ويب اللون) (Hex:#FF0000) (RGB:255, 0, 0)
- البرتقال (عجلة اللون البرتقالي) (Hex:#FF7F00) (RGB:255, 127, 0)
- الأصفر (ويب اللون) (Hex:#FFFF00) (RGB:255, 255, 0)
- الأخضر (X11) (الكهربائية الخضراء) (HTML/CSS "الجير") (عجلة اللون الأخضر) (Hex:#00FF00) (RGB:0, 255, 0)
- الأزرق (ويب اللون) (Hex:#0000FF) (RGB:0, 0, 255)
- النيلي (الكهربائية النيلي) (Hex:#6600FF) (RGB:102, 0, 255)
- البنفسجي (الكهربائية البنفسجي) (Hex:#8B00FF) (RGB:139, 0, 255)
بين كل لون جعل الخطية.
وهذه الفئة سوف نفعل ذلك مع PHP، تمرير المنشئ عدد الألوان التي تريدها في قوس قزح والممتلكات $ تسلسل سيتضمن مجموعة من رموز عرافة rrggbb.
class color
{
public $sequence = array();
/**
* constructor fills $sequence with a list of colours as long as the $count param
*/
public function __construct($count, $s = .5, $l = .5)
{
for($h = 0; $h <= .85; $h += .85/$count) //.85 is pretty much in the middle of the violet spectrum
{
$this->sequence[] = color::hexHSLtoRGB($h, $s, $l);
}
}
/**
* from https://stackoverflow.com/questions/3597417/php-hsv-to-rgb-formula-comprehension#3642787
*/
public static function HSLtoRGB($h, $s, $l)
{
$r = $l;
$g = $l;
$b = $l;
$v = ($l <= 0.5) ? ($l * (1.0 + $s)) : (l + $s - l * $s);
if ($v > 0){
$m;
$sv;
$sextant;
$fract;
$vsf;
$mid1;
$mid2;
$m = $l + $l - $v;
$sv = ($v - $m ) / $v;
$h *= 6.0;
$sextant = floor($h);
$fract = $h - $sextant;
$vsf = $v * $sv * $fract;
$mid1 = $m + $vsf;
$mid2 = $v - $vsf;
switch ($sextant)
{
case 0:
$r = $v;
$g = $mid1;
$b = $m;
break;
case 1:
$r = $mid2;
$g = $v;
$b = $m;
break;
case 2:
$r = $m;
$g = $v;
$b = $mid1;
break;
case 3:
$r = $m;
$g = $mid2;
$b = $v;
break;
case 4:
$r = $mid1;
$g = $m;
$b = $v;
break;
case 5:
$r = $v;
$g = $m;
$b = $mid2;
break;
}
}
return array('r' => floor($r * 255.0),
'g' => floor($g * 255.0),
'b' => floor($b * 255.0)
);
}
//return a hex code from hsv values
public static function hexHSLtoRGB($h, $s, $l)
{
$rgb = self::HSLtoRGB($h, $s, $l);
$hex = base_convert($rgb['r'], 10, 16) . base_convert($rgb['g'], 10, 16) . base_convert($rgb['b'], 10, 16);
return $hex;
}
}
لاختبار منها مثلا:
$c = new color(100);
foreach($c->sequence as $col)
print "<div style='background-color:#$col'>$col</div>\n";
وأنا فقط ينسب الفضل للتغليف هذا الأمر في طبقة، تم العثور على وظيفة الأصلي في هذا المنصب: HSV إلى RGB صيغة الفهم
وحلول أخرى تتطلب كميات كبيرة بدلا من رمز والمتفرعة المشروط، مما يجعلها غير صالحة للوحدات معالجة الرسومات. وصلت مؤخرا إلى ما يلي صيغة بسيطة سحرية في GLSL. انها في الأساس نفسه في OpenCL:
vec3 HueToRGB(float hue) {
vec3 h = vec3(hue, hue + 1.0/3.0, hue + 2.0/3.0);
return clamp(6.0 * abs(h - floor(h) - 0.5) - 1.0, 0.0, 1.0);
}
وهذا سوف يعطيك لون قوس قزح الذي يتوافق مع قيمة هوى الواردة في RGB الخطي. لاستخدامها في صورة، تحويل إلى sRGB ثم ضرب من قبل 255.
وهنا هو نسخة C ++:
float clamp(float value, float low, float high) {
return value < low ? low : (value > high ? high : value);
}
void HueToRGB(float hue, float *rgb) {
rgb[0] = hue;
rgb[1] = hue + 1.f/3.f;
rgb[2] = hue + 2.f/3.f;
for (unsigned i = 0; i < 3; ++i) {
rgb[i] = clamp(6.0f * fabsf(rgb[i] - floorf(rgb[i]) - 0.5f) - 1.f, 0.f, 1.f);
}
}
والمفتاح هنا هو أن ندرك أن الرسم البياني لكل من R، G، وينسق B في وظيفة من قيمة هوى هي قيمة فرضت وظيفة مثلث الدورية، والتي يمكن الحصول عليها كقيمة مطلقة من سن منشار وظيفة، x - floor(x)
.
وأنا أعلم أنه هو بالأحرى السؤال القديم، ولكن هنا هي لغتي بسيطة وسهلة الفهم الحل، الذي يجب أن يكون سهل الاستخدام في معظم لغات البرمجة. استبدال الخطوات وwhichStep مع القيم الخاصة بك.
int steps = 1280;
int stepChange = 1280 / steps;
int change = stepChange * whichStep;
int r=0, g=0, b=0;
if (change < 256)
{
r = 255;
g += change;
}
else if (change < 512)
{
r = 511 - change;
g = 255;
}
else if (change < 768)
{
g = 255;
b = change-512;
}
else if (change < 1024)
{
g = 1023 - change;
b = 255;
}
else
{
r = change - 1024;
b = 255;
}
وأنا يمكن رسم قوس قزح برمجيا مع جافا سكريبت وHTML5.
وأنا جعل التدرج من RGB (255،0،0) -> RGB (255،255،0) -> RGB (0،255،0) -> RGB (0255255) -> RGB (0،0،255) -> RGB ( 255،0،255).
وI حساب القيم لون عرافة على طول التدرج باستخدام بلدي RainbowVis-JS مكتبة (التي مجرد سلاسل التدرجات معا). أود أن ألفت قوس <م> شكل م> مع HTML5 قماش، حلقات من خلال الألوان.
<!DOCTYPE html>
<html>
<head>
<script src="rainbowvis.js"></script>
</head>
<body>
<script type="text/javascript">
window.onload = function(){
var RAINBOW_WIDTH = 60;
var RAINBOW_RADIUS = 130;
// Library class
var rainbow = new Rainbow();
rainbow.setNumberRange(1, RAINBOW_WIDTH);
rainbow.setSpectrum(
'FF0000', 'FFFF00', '00FF00',
'00FFFF', '0000FF', 'FF00FF'
);
// Canvas
var canvas = document.getElementById('MyCanvas');
var context = canvas.getContext('2d');
context.lineWidth = 1;
for (var i = 1; i <= RAINBOW_WIDTH; i++) {
context.beginPath();
context.arc(canvas.width/2, canvas.width/2, RAINBOW_RADIUS - i+1,
Math.PI, 0, false);
context.strokeStyle = '#' + rainbow.colourAt(i); // Library function
context.stroke();
}
};
</script>
<canvas id="MyCanvas" width="300" height="300">
<p>Rainbow arc example. Your browser doesn't support canvas.</p>
</canvas>
</body>
</html>