我想创建一个可以生成点对点渐变的应用程序(就像Photoshop一样)。我熟悉如何生成向上渐变而不是点对点。这是如何在概念上完成的。
由于
答案 0 :(得分:3)
我不能说这是完全 Photoshop是如何做到的,或者它是最佳的做法,但这应该是基本原则。
将这两点视为定义向量。你可以找到一个法向量,它将垂直于原始向量(因为这是法向量的定义)。
对于线上的每个离散点(像素),计算渐变颜色,就像使用与矢量长度相同的上下(或左右)渐变一样。然后绘制一条选定颜色的线,使其穿过当前选定的点并与法线向量平行。
它实际上非常类似于你用于上下渐变的方法,除了它被旋转。
答案 1 :(得分:2)
以Michael Madsen的回答为基础 -
对于您正在填充的区域中的每个点,计算线段上的最近点。 (你必须谷歌,但有很多例子。)在计算最近点的某个时刻,有一个计算的值,范围从起点的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。但无论如何......我想这会让你到那儿。也许很明显,前半部分是“静态的”所以你只需要循环过去四行。
答案 2 :(得分: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.
}
}