HSV 色空間の 2 つの色を補間して、滑らかな色のグラデーションを生成しようとしています。
私は線形補間を使用しています。例えば:
h = (1 - p) * h1 + p * h2
s = (1 - p) * s1 + p * s2
v = (1 - p) * v1 + p * v2
(ここで、p はパーセンテージで、h1、h2、s1、s2、v1、v2 は 2 つの色の色相、彩度、値のコンポーネントです)
これは、s と v に対しては良い結果をもたらしますが、h に対してはそうではありません。色相成分は角度であるため、計算では h1 と h2 の間の最短距離を計算し、正しい方向 (時計回りまたは反時計回り) に補間を行う必要があります。
どの式またはアルゴリズムを使用すればよいですか?
編集: ジャックの提案に従って、JavaScript グラデーション関数を変更したところ、うまく機能しました。興味のある人のために、これが私が最終的に得たものです:
// create gradient from yellow to red to black with 100 steps
var gradient = hsbGradient(100, [{h:0.14, s:0.5, b:1}, {h:0, s:1, b:1}, {h:0, s:1, b:0}]);
function hsbGradient(steps, colours) {
var parts = colours.length - 1;
var gradient = new Array(steps);
var gradientIndex = 0;
var partSteps = Math.floor(steps / parts);
var remainder = steps - (partSteps * parts);
for (var col = 0; col < parts; col++) {
// get colours
var c1 = colours[col],
c2 = colours[col + 1];
// determine clockwise and counter-clockwise distance between hues
var distCCW = (c1.h >= c2.h) ? c1.h - c2.h : 1 + c1.h - c2.h;
distCW = (c1.h >= c2.h) ? 1 + c2.h - c1.h : c2.h - c1.h;
// ensure we get the right number of steps by adding remainder to final part
if (col == parts - 1) partSteps += remainder;
// make gradient for this part
for (var step = 0; step < partSteps; step ++) {
var p = step / partSteps;
// interpolate h, s, b
var h = (distCW <= distCCW) ? c1.h + (distCW * p) : c1.h - (distCCW * p);
if (h < 0) h = 1 + h;
if (h > 1) h = h - 1;
var s = (1 - p) * c1.s + p * c2.s;
var b = (1 - p) * c1.b + p * c2.b;
// add to gradient array
gradient[gradientIndex] = {h:h, s:s, b:b};
gradientIndex ++;
}
}
return gradient;
}