具有角度和角度的线性梯度强度

时间:2016-09-29 16:56:14

标签: c++ gradient xojo

我希望在C ++ / RealBasic中实现一个函数,通过参数创建颜色渐变:

  1. 图像的宽度和高度
  2. 渐变的2种颜色
  3. 渐变的角度(方向)
  4. 渐变强度
  5. 以下链接显示了所需输出图像的一些示例: http://www.artima.com/articles/linear_gradients_in_flex_4.htmlhttp://i.stack.imgur.com/4ssfj.png

    我找到了多个例子,但它们只给我垂直和水平渐变,而我也想指定角度和强度。

    有人能帮助我吗?

    P.S。:我对几何学只知道一点!! :(

1 个答案:

答案 0 :(得分:0)

你的问题非常广泛,因为这是一个非常复杂的练习,包含大量代码,包括图像渲染,图像格式处理,将文件写入磁盘等。这些都不是单一功能的问题。因此,我专注于制作2种颜色的任意线性颜色渐变。

线性颜色渐变

您可以在两种颜色之间通过linear interpolation创建线性颜色“渐变”。然而,简单的线性插值使得转换看起来非常恶劣。对于视觉上更具吸引力的结果,我建议使用某种S-shaped插值曲线,例如基于Hermite插值的smoothstep

Linear color gradient

关于角度,您可以通过颜色渐变的起点(p0)和结束点(p1)定义线段。我们称之为d01之间的距离,d01 = distance(p0, p1)。然后,对于图像的每个像素点p,您必须计算此段上的最近点p2Here is an example如何做到这一点。然后计算t = distance(p0, p2) / d01。这将是[0,1]范围内的 lerp 参数t。 通过此t在2渐变颜色之间插值,您获得给定点p的颜色。

这可以通过多种方式实现。您可以使用OpenGL渲染图像,然后将像素缓冲区读回RAM。如果您不熟悉OpenGL或渲染过程,可以编写一个获取点(像素的2D坐标)并返回RGB颜色的函数 - 这样您就可以计算图像的所有像素。最后,您可以使用图像格式将图像写入磁盘,但这是另一个故事。

以下是上述某些功能的示例C ++ 14实现。

简单线性插值:

template <typename T, typename U>
T lerp(const T &a, const T &b, const U &t)
{
    return (U(1) - t)*a + t*b;
}

,其中ab是两个值(在这种情况下为颜色),您希望在它们之间进行插值,t是范围[0,1]中的插值参数表示ab之间的转换。

当然上面的函数需要一个类型T,它支持乘以标量。您可以简单地使用任何3D矢量类型,因为颜色实际上是颜色空间中的坐标。

两个2D点之间的距离:

#include <cmath>

auto length(const Point2 &p)
{
    return std::sqrt(p.x*p.x + p.y*p.y);
}

auto distance(const Point2 &a, const Point2 &b)
{
    Point delta = b - a;
    return length(delta);
}

来自https://developer.mozilla.org/en-US/docs/Web/CSS/linear-gradient的图片