0

我想制作一个可以生成点对点渐变的应用程序(就像 Photoshop 一样)。我熟悉如何生成从上到下的渐变,但不是点对点。这在概念上是如何完成的。

谢谢

4

3 回答 3

3

我不能说这是否正是Photoshop 的做法,或者说这是最佳的做法,但这应该是基本原则。

将这两点视为定义一个向量。您可以为此找到一个法线向量,它将垂直于原始向量(因为这是法线向量的定义)。

对于线上的每个离散点(像素),计算渐变颜色,就像计算与向量长度相同的上下(或左右)渐变。然后绘制一条选定颜色的线,使其穿过当前选定的点并与法向量平行。

它实际上与您用于上下渐变的方法非常相似,只是它是旋转的。

于 2010-05-19T23:32:58.497 回答
2

基于迈克尔·马德森的回答——

对于要填充的区域中的每个点,计算线段上的最近点。(你必须用谷歌搜索,但有很多例子。)在计算最近点的某个时刻,计算出的值的范围从起点的 0 到终点的 1。将其插入到您的渐变函数中。

该算法的概述基本上是......

pc = # the point you are coloring now
p0 = # start point
p1 = # end point
v = p1 - p0
d = Length(v)
v = Normalize(v) # or Scale(v, 1/d)

v0 = pc - p0

t = Dot(v0, v)
t = Clamp(t/d, 0, 1)

color = (start_color * t) + (end_color * (1 - t))

如果您将 v 缩放 1/d^2 而​​不是 1/d,您实际上可能会失去 make t/d just t。但无论如何......我认为这会让你到达那里。也许很明显,前半部分是“静态的”,所以你只需要遍历最后四行。

于 2010-05-20T00:09:57.363 回答
0

此例程为图像中的每个点调用您的函子,并使用适当的值。使用该值作为颜色查找表的索引,您将获得混合。Functor 有这个原型:void (int x, int y, int value)。

/** Produce a linear gradient.

    This implementation uses float values.
*/
struct Linearf
{
  template <class Functor>
  void operator() (
    int rows,
    int cols,
    int x0, int y0,
    int x1, int y1,
    int const scale,
    Functor f)
  {
    if (x0 != x1)
    {
      // 1/m'
      float const m = float (y1 - y0) / (x0 - x1);

      for (int y = 0; y < rows; ++y)
      {
        float const p0 = m * (y - y0) + x0;
        float const p1 = m * (y - y1) + x1;
        float const d = (scale + 0.9999f) / (p1 - p0);

        for (int x = 0; x < cols; ++x)
        {
          if (x < p0)
          {
            f (x, y, 0);
          }
          else if (x >= p1)
          {
            f (x, y, scale);
          }
          else
          {
            f (x, y, d * (x - p0));
          }
        }
      }
    }
    else
    {
      // Special case for horizontal lines.
    }
  }
于 2012-08-30T17:08:11.183 回答