使用SVG渐变“自然地”着色三角形

时间:2010-07-05 22:41:45

标签: math svg

我有3个点H1,H2和H3,其中每个Hi都有100% 饱和度和值,只有色调变化。换句话说,这些 是“彩虹”的颜色。

我想使用SVG的渐变功能为三角形着色 “自然”。换句话说,接近H1的点应该有hue H1, 着色应该是连续的等等。

这个问题定义明确吗?真的有这种(独特的?)着色吗?

轻微:我不认为色调“环绕”。换句话说, 色调.995和.003之间的颜色是.499,而不是.999。

如果此问题有解决方案,可以将其扩展为“自然” 使用平面上任何一组彩色点的凸包颜色 Delaunay三角测量?

5 个答案:

答案 0 :(得分:7)

这个线程已经死了,我意识到了。但我发布这个答案,希望它对未来的某些人有用。如果你可以将方程扩展到正确的SVG标记,那么我们就完成了它。我为可可开发了这个特殊的解决方案,但数学是完全相关的。

该方法涉及一个小矩阵数学,以找到三角形的梯度向量,它给出了相对于z的最陡上升的(x,y)方向 - 这是颜色渐变的方向。颜色梯度的起点/终点由梯度向量斜率(通过x,y原点约束)与描述zmin和zmax的三角形平面上的等值线的交点确定。

首先,可以用等式描述与三角形的三个点{p1, p2, p3}相交的平面:

A1(x) + A2(y) + A3(z) - A = 0

其中A是决定因素:

    |p1x  p1y  p1z|
A = |p2x  p2y  p2z|
    |p3x  p3y  p3z|

Ai是相同的决定因素,但将列i替换为列向量:

            1                     |p1x  1  p1z|
column(i) = 1          e.g., A2 = |p2x  1  p2z|
            1                     |p3x  1  p3z|

渐变向量grad(z)描述了最陡上升的方向,这也是颜色渐变的轨迹:

grad(z) = [-A1/A3 (i), -A2/A3 (j)]

所以在x,y平面上,这个梯度向量位于一条直线上:

y = x * A2/A1 + b, 

其中b可以是任何东西,但是让我们设置b = 0。这会将颜色渐变轨迹限制为与原点相交的直线:

y = x * A2/A1                 [eqn 1]

此行描述颜色渐变方向。起点和终点将由该线与zmax和zmin等线的交点确定。

现在,对于任何定义的值zmaxzmin,我们可以描述由三角形定义的平面上的平行线:

A1(x) + A2(y) + A3(zmax) - A = 0                 [eqn 2]
and
A1(x) + A2(y) + A3(zmin) - A = 0                 [eqn 3]

使用上面的公式1-3,我们可以分别求解G1G2,颜色渐变的起点和终点。

G1 = (xmin,ymin)
G2 = (xmax,ymax)

,其中

xmin = (A - A3*zmin) / (A1 + A2^2 / A1)
ymin = xmin * A2/A1

xmax = (A - A3*zmax) / (A1 + A2^2 / A1)
ymax = xmax * A2/A1

注意A1 = 0的特殊情况,对应于完全垂直的颜色渐变路径。在这种情况下:

for A1 == 0:

G1 = (0,ymin)
G2 = (0,ymax),
where
ymin = (A - A3*zmin) / A2
ymax = (A - A3*zmax) / A2

唯一的另一个特例是p1z = p2z = p3z。这将尝试将渐变路径拉伸为无限长。在这种特殊情况下,三角形应该是固定的,而不是通过所有数学。

剩下的就是将三角形设置为剪切区域并绘制从G1G2的渐变。我将包含一个问题域图和相关的线性方程。另请注意,颜色渐变沿着每个三角形边缘线性变化,因此OP关于delaunay三角剖分的问题正好在目标上。出于这个原因,我开发了这种方法 - 为三角网格的面部着色。下图显示了zmax == p3z > p1z > p2z > zmin

的情况

three-point gradient vector solution

答案 1 :(得分:5)

您需要多个渐变才能在三角形上实现所需的渐变,因为渐变是颜色空间中两个点之间的插值,但您有三个不同的非共线点。使用重心插值,您应该为每个顶点应用一个渐变,使得渐变方向在垂直于相对边缘的方向上远离顶点。当渐变到达边缘时,渐变从顶点的完全饱和度开始到零饱和度。

barycentric interpolation on convex polygons有各种类似物,但我没有详细阅读那篇论文,知道它是否可以作为线性渐变的叠加来实现。

最后,你的问题归结为多边形内的插值,每个插值方案都会产生不同的(可能是唯一的)着色。

答案 2 :(得分:1)

也许你应该检查Gouraud Shading,这似乎适合你要找的东西。它在三角形的顶点上插入给定的三种颜色。

答案 3 :(得分:1)

可以将svg渐变与svg滤镜结合使用来创建某些效果,类似于我认为你要求的效果。

这里可以看到一些例子:http://www.chaos.org.uk/~eddy/when/2006/ColourCube.xhtml(我建议在Opera查看结果,其他浏览器似乎没有正确渲染融合渐变)。有关应用于三角形的三向渐变的示例,请参阅here

答案 4 :(得分:1)

如果色调没有环绕它很容易,但解决方案并不是唯一的。

假设三种色调不同,比如H1<H2<H3

你将在加入x 1 和x 3 的段中找到一个点x 4 (这是你有选择的地方) ,让整行连接x 2 和x 4 相同的颜色H 2 。然后定义垂直于此线的渐变,具有所需的距离,例如为三个点提供正确的色调。

x 4 点的一种可能选择是色调在x 1 和x 3 之间线性变化。另一个是垂直的脚。任何固定的解决方案都不会与具有两个共同顶点的不同trianngle连接,因此对于一般着色它没有任何帮助。

相关问题