我正在尝试在HSV颜色空间中插入两种颜色之间以产生平滑的颜色渐变.
我正在使用线性插值,例如:
h = (1 - p) * h1 + p * h2
s = (1 - p) * s1 + p * s2
v = (1 - p) * v1 + p * v2
Run Code Online (Sandbox Code Playgroud)
(其中p是百分比,h1,h2,s1,s2,v1,v2是两种颜色的色调,饱和度和值分量)
这对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 …Run Code Online (Sandbox Code Playgroud) 我用这个代码用一个Lineargradient做了一个色调渐变:(我知道它本来可以变得更简单Color.parseColor但是我必须这样做.我也不能使用drawable.)
colors = new int[]{ Color.HSVToColor(new float[]{0, 1, 1}),
Color.HSVToColor(new float[]{60, 1, 1}),
Color.HSVToColor(new float[]{120, 1, 1}),
Color.HSVToColor(new float[]{180, 1, 1}),
Color.HSVToColor(new float[]{240, 1, 1}),
Color.HSVToColor(new float[]{300, 1, 1}),
Color.HSVToColor(new float[]{360, 1, 1}) };
Shader shader = new LinearGradient(0, 0, width, 0, colors, null, Shader.TileMode.CLAMP);
paint.setShader(shader);
Run Code Online (Sandbox Code Playgroud)
产生这种结果的颜色略有偏移,绿色区域太小,蓝色区域与预期结果相比太大.
我查了一切.我尝试使用new float[]{0f, 1/6f, 2/6f, 3/6f, 4/6f, 5/6f, 1f}而不是null位置参数,相同的结果.这可能也是一个错误.
请注意,这不是重复这个帖子也不是这一个.这些是关于在代码中设置的不正确的渐变停止,这不是我的情况.它可能与这个有关,但我不知道如何.
编辑:也许这可以通过设置不相等的位置来解决,但我怎样才能计算出这些确切的位置?